pax_global_header00006660000000000000000000000064126504013730014513gustar00rootroot0000000000000052 comment=148631cc993cd06b3060ca32968ccf8e86bb41e0 libp11-libp11-0.3.1/000077500000000000000000000000001265040137300136725ustar00rootroot00000000000000libp11-libp11-0.3.1/.gitignore000066400000000000000000000011611265040137300156610ustar00rootroot00000000000000Makefile Makefile.in core archive acinclude.m4 aclocal.m4 autom4te.cache compile confdefs.h config.* configure conftest conftest.c depcomp install-sh libtool libtool.m4 ltmain.sh missing mkinstalldirs so_locations stamp-h* .deps .libs .#*# .*.bak .*.orig .*.rej .*~ #*# *.bak *.d *.def *.dll *.exe *.la *.lib *.lo *.o *.orig *.pdb *.rej *.u *.res *.pc *~ *.gz *.bz2 *.out *.exp *.obj m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 examples/auth examples/decrypt examples/getrandom examples/rawrsasign examples/listkeys test-driver tests/fork-test tests/*.log tests/*.trs tests/output.* doc/doxygen.conf libp11-libp11-0.3.1/.travis.sh000077500000000000000000000036021265040137300156200ustar00rootroot00000000000000#!/bin/sh set -e # # Copyright (c) 2016 Michał Trojnara # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. install_from_github() { echo "Installing $2" git clone https://github.com/$1/$2.git cd $2 autoreconf -fvi ./configure make sudo -E make install cd .. echo "$2 installed" sudo ldconfig } # ppa:pkg-opendnssec provides a less-obsolete softhsm sudo apt-add-repository -y ppa:pkg-opendnssec/ppa sudo apt-get update -qq # libpcsclite-dev is required for OpenSC # softhsm is required for "make check" sudo apt-get install -y libpcsclite-dev softhsm export CC=`which $CC` mkdir prerequisites cd prerequisites install_from_github OpenSC OpenSC cd .. rm -rf prerequisites libp11-libp11-0.3.1/.travis.yml000066400000000000000000000003321265040137300160010ustar00rootroot00000000000000sudo: true language: c compiler: - clang - gcc before_script: - ./.travis.sh - touch config.rpath && autoreconf -fvi && ./configure --enable-strict --enable-pedantic script: make && make check && make dist libp11-libp11-0.3.1/COPYING000066400000000000000000000636401265040137300147360ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! libp11-libp11-0.3.1/INSTALL.md000066400000000000000000000011331265040137300153200ustar00rootroot00000000000000# libp11 Installation ## Unix Build Install the OpenSSL development package. On Debian/Ubuntu use: sudo apt-get install libssl-dev Build and install libp11: ./configure && make && sudo make install ## Windows Build Download and install OpenSSL, for example: * https://slproweb.com/download/Win32OpenSSL-1_0_2e.exe * https://slproweb.com/download/Win64OpenSSL-1_0_2e.exe ### MSVC To build libp11 use: nmake -f Makefile.mak In case your OpenSSL is installed in a different directory, use: nmake -f Makefile.mak OPENSSL_DIR=\your\openssl\directory ### Mingw TODO ### Cygwin TODO libp11-libp11-0.3.1/Makefile.am000066400000000000000000000014141265040137300157260ustar00rootroot00000000000000AUTOMAKE_OPTIONS = foreign 1.10 ACLOCAL_AMFLAGS = -I m4 MAINTAINERCLEANFILES = \ config.log config.status \ $(srcdir)/configure $(srcdir)/Makefile.in \ $(srcdir)/install-sh $(srcdir)/ltmain.sh $(srcdir)/missing \ $(srcdir)/depcomp $(srcdir)/aclocal.m4 \ $(srcdir)/config.guess $(srcdir)/config.sub \ $(srcdir)/m4/ltsugar.m4 $(srcdir)/m4/libtool.m4 \ $(srcdir)/m4/ltversion.m4 $(srcdir)/m4/lt~obsolete.m4 \ $(srcdir)/m4/ltoptions.m4 \ $(srcdir)/packaged EXTRA_DIST = .gitignore Makefile.mak README.md dist_noinst_DATA = COPYING INSTALL.md dist_doc_DATA = NEWS # Prerequisites must be first on the list SUBDIRS = src doc examples tests # Allow detection of packaged tarball dist-hook: $(MKDIR_P) "$(distdir)/m4" echo > "$(distdir)/packaged" # vim: set noexpandtab: libp11-libp11-0.3.1/Makefile.mak000066400000000000000000000002131265040137300160750ustar00rootroot00000000000000 SUBDIRS = src all:: all depend install clean:: @for %i in ( $(SUBDIRS) ) do \ @cmd /c "cd %i && $(MAKE) /nologo /f Makefile.mak $@" libp11-libp11-0.3.1/NEWS000066400000000000000000000057611265040137300144020ustar00rootroot00000000000000NEWS for Libp11 -- History of user visible changes New in 0.3.1; 2016-01-22; Michał Trojnara * Added PKCS11_is_logged_in to the API (Mikhail Denisenko) * Added PKCS11_enumerate_public_keys to the API (Michał Trojnara) * Fixed EVP_PKEY handling of public keys (Michał Trojnara) * Added thread safety based on OpenSSL dynamic locks (Michał Trojnara) * A private index is allocated for ex_data access (RSA and ECDSA classes) instead of using the reserved index zero (app_data) (Michał Trojnara) * Fixes in reinitialization after fork; addresses #39 (Michał Trojnara) * Improved searching for dlopen() (Christoph Moench-Tegeder) * MSVC build fixes (Michał Trojnara) * Fixed memory leaks in pkcs11_get_evp_key_rsa() (Michał Trojnara) New in 0.3.0; 2015-10-09; Nikos Mavrogiannopoulos * Added small test suite based on softhsm (run on make check) * Memory leak fixes (Christian Heimes) * On module initialization tell the module to that the OS locking primitives are OK to use (Mike Gerow) * Transparently handle applications that fork. That is call C_Initialize() and reopen any handles if a fork is detected. * Eliminated any hard coded limits for certificate size (Doug Engert) * Added support for ECDSA (Doug Engert) * Allow RSA_NO_PADDING padding mode in PKCS11_private_encrypt (Stephane Adenot) * Eliminated several hard-coded limits in parameter sizes. New in 0.2.8; 2011-04-15; Martin Paljak * Bumped soname for PKCS11_token struct size changes (Martin Paljak). * Display the number of available slots (Ludovic Rousseau). * Add openssl libcrypto to pkg-config private libs list (Kalev Lember). * Fix building examples with --no-add-needed which is the default in Fedora (Kalev Lember). * Expose more token flags in PKCS11_token structure (Kalev Lember). * Check that private data is not NULL in pkcs11_release_slot (Robin Bryce, ticket #137). New in 0.2.7; 2009-10-20; Andreas Jellinghaus * If CKR_CRYPTOKI_ALREADY_INITIALIZED is returned from C_Initialize(): ignore. (Needed for unloaded/reloaded engines e.g. in wpa_supplicant.) By David Smith. New in 0.2.6; 2009-07-22; Andreas Jellinghaus * Fix new version: add new symbol to export file * fix building on MSVC plattform New in 0.2.5; 2009-06-15; Andreas Jellinghaus * Add function to export the slot id (Douglas E. Engert). * Increase library version because of the new function. New in 0.2.4; 2008-07-31; Andreas Jellinghaus * Build system rewritten (NOTICE: configure options was modified). The build system can produce outputs for *NIX, cygwin and native windows (using mingw). * added PKCS11_CTX_init_args (David Smith). * fix segfault in init_args code. * implemented PKCS11_private_encrypt (with PKCS11_sign now based on it) (Arnaud Ebalard) New in 0.2.3; 2007-07-11; Andreas Jellinghaus * update wiki export script (add images, fix links). * replaced rsa header files from rsalabs (official) with scute (open source). * allow CKR_USER_ALREADY_LOGGED_IN on C_Login. * mark internal functions as static. * add code to store public keys and generate keys. libp11-libp11-0.3.1/README.md000066400000000000000000000021571265040137300151560ustar00rootroot00000000000000Build state =========== [![Build Status](https://travis-ci.org/OpenSC/libp11.png)](https://travis-ci.org/OpenSC/libp11) [![Build status](https://ci.appveyor.com/api/projects/status/kmbu8nex5ogecoiq?svg=true)](https://ci.appveyor.com/project/LudovicRousseau/libp11) libp11 README -- Information for developers =========================================== This library provides a higher-level (compared to the PKCS#11 library) interface to access PKCS#11 objects. It is designed to integrate with applications that use OpenSSL. Thread-safety requires dynamic callbacks to be registered by the calling application with the following OpenSSL functions: * CRYPTO_set_dynlock_create_callback * CRYPTO_set_dynlock_destroy_callback * CRYPTO_set_dynlock_lock_callback The wiki page for this project is at https://github.com/OpenSC/libp11/wiki and includes a bug tracker and source browser. Submitting pull requests ======================== For adding new features or extending functionality in addition to the code, please also submit a test program which verifies the correctness of operation. See tests/ for the existing test suite. libp11-libp11-0.3.1/appveyor.yml000066400000000000000000000035761265040137300162750ustar00rootroot00000000000000version: 0.3.1.{build} platform: - x86 - x64 configuration: - Release - Debug environment: matrix: - VSVER: 12 # - VSVER: 10 install: - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` throw "There are newer queued builds for this pull request, failing early." } - date /T & time /T - set OPENSSL_VER=1_0_2e - ps: >- If ($env:Platform -Match "x86") { $env:VCVARS_PLATFORM="x86" $env:ENV_PLATFORM="x86" $env:NMAKE_ARCH="" $env:OPENSSL_PF="Win32" } Else { $env:VCVARS_PLATFORM="amd64" $env:ENV_PLATFORM="x64" $env:NMAKE_ARCH="BUILD_ON=WIN64 BUILD_FOR=WIN64" $env:OPENSSL_PF="Win64" } - ps: >- If (!(Test-Path -Path "C:\OpenSSL-${env:OPENSSL_PF}" )) { Start-FileDownload https://slproweb.com/download/${env:OPENSSL_PF}OpenSSL-${env:OPENSSL_VER}.exe -FileName C:\WinOpenSSL.exe C:\WinOpenSSL.exe /SILENT /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART } - ps: >- If ($env:Configuration -Like "*Debug*") { $env:NMAKE_EXTRA="DEBUG=yes ${env:NMAKE_EXTRA}" } - ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS")) - echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%" - call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM% build_script: - nmake /f Makefile.mak %NMAKE_ARCH% %NMAKE_EXTRA% - appveyor PushArtifact src\libp11.dll - appveyor PushArtifact src\libp11.lib - ps: >- If ($env:Configuration -Like "*Debug*") { Push-AppveyorArtifact src\libp11.pdb } cache: - C:\OpenSSL-Win32 - C:\OpenSSL-Win64 libp11-libp11-0.3.1/bootstrap000077500000000000000000000000611265040137300156320ustar00rootroot00000000000000#!/bin/sh autoreconf --verbose --install --force libp11-libp11-0.3.1/configure.ac000066400000000000000000000116571265040137300161720ustar00rootroot00000000000000dnl -*- mode: m4; -*- AC_PREREQ(2.60) define([PACKAGE_VERSION_MAJOR], [0]) define([PACKAGE_VERSION_MINOR], [3]) define([PACKAGE_VERSION_FIX], [1]) define([PACKAGE_SUFFIX], []) AC_INIT([libp11],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX]) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_HEADERS([src/config.h]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([subdir-objects]) LIBP11_VERSION_MAJOR="PACKAGE_VERSION_MAJOR" LIBP11_VERSION_MINOR="PACKAGE_VERSION_MINOR" LIBP11_VERSION_FIX="PACKAGE_VERSION_FIX" # LT Version numbers, remember to change them just *before* a release. # (Code changed: REVISION++) # (Oldest interface removed: OLDEST++) # (Interfaces added: CURRENT++, REVISION=0) LIBP11_LT_CURRENT="5" LIBP11_LT_OLDEST="2" LIBP11_LT_REVISION="0" LIBP11_LT_AGE="$((${LIBP11_LT_CURRENT}-${LIBP11_LT_OLDEST}))" AC_CONFIG_SRCDIR([src/libp11.h]) # silent build by default ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_CANONICAL_HOST AC_PROG_CC PKG_PROG_PKG_CONFIG AC_C_BIGENDIAN AC_ARG_WITH( [cygwin-native], [AS_HELP_STRING([--with-cygwin-native],[compile native win32])], , [with_cygwin_native="no"] ) dnl Check for some target-specific stuff test -z "${WIN32}" && WIN32="no" test -z "${CYGWIN}" && CYGWIN="no" case "${host}" in *-mingw*|*-winnt*) WIN32="yes" CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN" WIN_LIBPREFIX="lib" ;; *-cygwin*) AC_MSG_CHECKING([cygwin mode to use]) CYGWIN="yes" if test "${with_cygwin_native}" = "yes"; then AC_MSG_RESULT([Using native win32]) CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN" CFLAGS="${CFLAGS} -mno-cygwin" WIN32="yes" else AC_MSG_RESULT([Using cygwin]) CPPFLAGS="${CPPFLAGS} -DCRYPTOKI_FORCE_WIN32" WIN_LIBPREFIX="cyg" AC_DEFINE([USE_CYGWIN], [1], [Define if you are on Cygwin]) fi ;; esac AC_ARG_ENABLE( [strict], [AS_HELP_STRING([--enable-strict],[enable strict compile mode @<:@disabled@:>@])], , [enable_strict="no"] ) AC_ARG_ENABLE( [pedantic], [AS_HELP_STRING([--enable-pedantic],[enable pedantic compile mode @<:@disabled@:>@])], , [enable_pedantic="no"] ) AC_ARG_ENABLE( [api-doc], [AS_HELP_STRING([--enable-api-doc],[enable generation and installation of api documents @<:@disabled@:>@])], , [enable_api_doc="no"] ) AC_ARG_WITH( [apidocdir], [AS_HELP_STRING([--with-apidocdir],[put API documents at this directory @<:@HTMLDIR/api@:>@])], [apidocdir="${with_apidocdir}"], [apidocdir="\$(htmldir)/api"] ) dnl Checks for programs. AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MKDIR_P AC_PROG_SED AC_PROG_MAKE_SET dnl Add libtool support. ifdef( [LT_INIT], [ LT_INIT([win32-dll]) LT_LANG([Windows Resource]) ], [ AC_LIBTOOL_WIN32_DLL AC_LIBTOOL_RC AC_PROG_LIBTOOL ] ) dnl Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS([ \ errno.h fcntl.h malloc.h stdlib.h \ inttypes.h string.h strings.h sys/time.h \ unistd.h locale.h getopt.h dlfcn.h utmp.h \ ]) AC_ARG_VAR([DOXYGEN], [doxygen utility]) AC_CHECK_PROGS([DOXYGEN],[doxygen]) test "${enable_api_doc}" = "yes" -a -z "${DOXYGEN}" && AC_MSG_ERROR([doxygen is required for api doc]) if test "${WIN32}" != "yes"; then AC_SEARCH_LIBS( [dlopen], [dl], , [AC_MSG_ERROR([dlopen required])] ) AC_CHECK_FUNCS([__register_atfork],,) fi PKG_CHECK_MODULES( [OPENSSL], [libcrypto >= 0.9.7], , [PKG_CHECK_MODULES( [OPENSSL], [openssl >= 0.9.7], , [AC_CHECK_LIB( [crypto], [RSA_version], [OPENSSL_LIBS="-lcrypto"], [AC_MSG_ERROR([Cannot find OpenSSL])] )] )] ) pkgconfigdir="\$(libdir)/pkgconfig" AC_SUBST([pkgconfigdir]) AC_SUBST([apidocdir]) AC_SUBST([PTHREAD_FLAGS]) AC_SUBST([LIBP11_VERSION_MAJOR]) AC_SUBST([LIBP11_VERSION_MINOR]) AC_SUBST([LIBP11_VERSION_FIX]) AC_SUBST([LIBP11_LT_CURRENT]) AC_SUBST([LIBP11_LT_REVISION]) AC_SUBST([LIBP11_LT_AGE]) AC_SUBST([LIBP11_LT_OLDEST]) AC_SUBST([WIN_LIBPREFIX]) AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) AM_CONDITIONAL([CYGWIN], [test "${CYGWIN}" = "yes"]) AM_CONDITIONAL([ENABLE_API_DOC], [test "${enable_api_doc}" = "yes"]) if test "${enable_pedantic}" = "yes"; then enable_strict="yes"; CFLAGS="${CFLAGS} -pedantic" fi if test "${enable_strict}" = "yes"; then CFLAGS="${CFLAGS} -Wall -Wextra" fi AC_CONFIG_FILES([ Makefile src/Makefile src/libp11.pc src/versioninfo.rc doc/Makefile doc/doxygen.conf examples/Makefile tests/Makefile ]) AC_OUTPUT cat <
libp11, Copyright (C) 2005 Olaf Kirch <okir@lst.de>OpenSC-Project.org Logo
libp11-libp11-0.3.1/doc/doxygen.conf.in000066400000000000000000001531731265040137300174020ustar00rootroot00000000000000# Doxyfile 1.5.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file that # follow. The default is UTF-8 which is also the encoding used for all text before # the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into # libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of # possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = libp11 # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = api.out # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = @top_srcdir@/src # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct (or union) is # documented as struct with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code where the coding convention is that all structs are # typedef'ed and only the typedef is referenced never the struct's name. TYPEDEF_HIDES_STRUCT = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be extracted # and appear in the documentation as a namespace called 'anonymous_namespace{file}', # where file will be replaced with the base name of the file that contains the anonymous # namespace. By default anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = YES # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = NO # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text " # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @top_srcdir@/src # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default # input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. # See http://www.gnu.org/software/libiconv for the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = libp11.h # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.svn/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the output. # The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH # then you must also enable this option. If you don't then doxygen will produce # a warning and turn it on anyway SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = @srcdir@/doxygen-footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to # produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to # specify the directory where the mscgen tool resides. If left empty the tool is assumed to # be found in the default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the number # of direct children of the root node in a graph is already larger than # MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO libp11-libp11-0.3.1/doc/opensc-logo.gif000066400000000000000000000110671265040137300173600ustar00rootroot00000000000000GIF89a2XKJL (+4cba $j̱5 14fr!ȩQȴQ˔{z{3賀uZ'4ɴ#zx$f$ӵ77btF cֵ naHR1Dpm+a  CsJ ZoDON"ǭ<@( Љ@!?, j AqŖ ,1\"d8mlE):Pc ]@GCpC] i!1`@8K\r@xhVB!ad8+㎳yCP05L矟nyӄY$yhD6`s r|:B T(|F{9K:5DW>Bw+qol5 ,t?(a^ } Q}Vmf \8:D¼!B0>@ڃ,H؂1$vb=? S@I& r\ے^iC>ew9h1K SC$'j@m@e7 |P{\uJ,  3)9x@kpi4! T 9!SwTxM~6hP&,{lZ, 2T5i ]@ψ08L&Z(9*Jf}bkkR > tc YS-^{JT@{:B#@w@-F!:(lʤ{@*hRpo1 ,:2YyF <[ C._k -0؆/;o@@@хbUmr%@ZFXh0,[L)Y1$jPq|M 䍁`ي+m #1+vSk7>r("+g=|yW tpAh='>*IG - 8dA(Bun.If@)7f1 >ax#|*L Ĉid"y P@tQ15ӅfTꕿ՚! $Z14=eu:@&>Jxķ.;3OYO O4D^A8yv$\ uŤ)M0+6Fp Dqh5@A}f VЬG &n P?p^j9C>5@ȼ1V_6rusj r & OHz0Xb0huMV+ /xk0J}NyA X#YKd^B  @s?rѤPa >9c}u]{W|~|]p8r Mx xחsGFYogofY4T YG.k~Uwk ) />ZAA[Q$l 2$2+  s6|G^#3w|۰ PBDp BPdSi}'jއDjUyL%Ё2~5iӳKat:O Ar`:575ME*4(>h0  ~Cw1cŗ(-R)" @V[4dtJ%R3)H@@ U5h2A 2 jC6 Wt0 Bb{} ۠0dQ Z  _@0 ezY0U PrZ YpTpꇋD4?`#˰4>76l !b:#nP0g0m0 p f0o a/< wp~4yySJH2vH%*)0 ԀJAIzv+W@ 2ʁY9pŦ w:Peh+ B?)P1x4S|| F1ay7U`UAV0jZG0  R3@%`*v Fn/ )ޢrp P#&L$-HaЂGG$J'^#| pyfZ@_ki_Dp( PYR$8~f(uy'( Jya۷\7^񁁥hCA| IPpm 빟뷰qL"Ycƺ;&# ̀]{⸽,KP 8W ©[u8 k(;libp11-libp11-0.3.1/examples/000077500000000000000000000000001265040137300155105ustar00rootroot00000000000000libp11-libp11-0.3.1/examples/Makefile.am000066400000000000000000000003701265040137300175440ustar00rootroot00000000000000AM_CFLAGS = $(OPENSSL_CFLAGS) AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)/src \ -I$(top_builddir)/ EXTRA_DIST = README noinst_PROGRAMS = auth decrypt getrandom listkeys rawrsasign LDADD = ../src/libp11.la $(OPENSSL_LIBS) # vim: set noexpandtab: libp11-libp11-0.3.1/examples/README000066400000000000000000000012711265040137300163710ustar00rootroot00000000000000Libp11 example code =================== This directory contains some example code how to use libp11. Feel free to use this code in any way, it is public domain, not copyrighted. auth.c Example for authentication, i.e. get the first token, get the first certificate, ask for pin, login, sign some random data, and verify the signature using the certificate/public key. For easy building see the Makefile in this directory. If you are using autoconf/automake/libtool, you might want to add to your configure.ac file: PKG_CHECK_MODULES([LIBP11], [libp11]) and to your Makefile.am: bin_PROGRAMS = myapp myapp_CFLAGS = @LIBP11_CFLAGS@ myapp_LIBADD = @LIBP11_LIBS@ myapp_SOURCES = myapp.c libp11-libp11-0.3.1/examples/auth.c000066400000000000000000000130171265040137300166170ustar00rootroot00000000000000/* libp11 example code: auth.c * * This examply simply connects to your smart card * and does a public key authentication. * * Feel free to copy all of the code as needed. * */ #include #include #include #include #include #include #include #include #define RANDOM_SOURCE "/dev/urandom" #define RANDOM_SIZE 20 #define MAX_SIGSIZE 256 int main(int argc, char *argv[]) { PKCS11_CTX *ctx; PKCS11_SLOT *slots, *slot; PKCS11_CERT *certs; PKCS11_KEY *authkey; PKCS11_CERT *authcert; EVP_PKEY *pubkey = NULL; unsigned char *random = NULL, *signature = NULL; char password[20]; int rc = 0, fd, logged_in; unsigned int nslots, ncerts, siglen; if (argc < 2) { fprintf(stderr, "usage: auth /usr/lib/opensc-pkcs11.so [PIN]\n"); return 1; } ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(ctx, argv[1]); if (rc) { fprintf(stderr, "loading pkcs11 engine failed: %s\n", ERR_reason_error_string(ERR_get_error())); rc = 1; goto nolib; } /* get information on all slots */ rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); if (rc < 0) { fprintf(stderr, "no slots available\n"); rc = 2; goto noslots; } /* get first slot with a token */ slot = PKCS11_find_token(ctx, slots, nslots); if (slot == NULL || slot->token == NULL) { fprintf(stderr, "no token available\n"); rc = 3; goto notoken; } printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); if (!slot->token->loginRequired) goto loggedin; /* get password */ if (argc > 2) { strcpy(password, argv[2]); } else { struct termios old, new; /* Turn echoing off and fail if we can't. */ if (tcgetattr(0, &old) != 0) goto failed; new = old; new.c_lflag &= ~ECHO; if (tcsetattr(0, TCSAFLUSH, &new) != 0) goto failed; /* Read the password. */ printf("Password for token %.32s: ", slot->token->label); if (fgets(password, sizeof(password), stdin) == NULL) goto failed; /* Restore terminal. */ (void)tcsetattr(0, TCSAFLUSH, &old); /* strip tailing \n from password */ rc = strlen(password); if (rc <= 0) goto failed; password[rc-1]=0; } loggedin: /* check if user is logged in */ rc = PKCS11_is_logged_in(slot, 0, &logged_in); if (rc != 0) { fprintf(stderr, "PKCS11_is_logged_in failed\n"); goto failed; } if (logged_in) { fprintf(stderr, "PKCS11_is_logged_in says user is logged in, expected to be not logged in\n"); goto failed; } /* perform pkcs #11 login */ rc = PKCS11_login(slot, 0, password); memset(password, 0, strlen(password)); if (rc != 0) { fprintf(stderr, "PKCS11_login failed\n"); goto failed; } /* check if user is logged in */ rc = PKCS11_is_logged_in(slot, 0, &logged_in); if (rc != 0) { fprintf(stderr, "PKCS11_is_logged_in failed\n"); goto failed; } if (!logged_in) { fprintf(stderr, "PKCS11_is_logged_in says user is not logged in, expected to be logged in\n"); goto failed; } /* get all certs */ rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts); if (rc) { fprintf(stderr, "PKCS11_enumerate_certs failed\n"); goto failed; } if (ncerts <= 0) { fprintf(stderr, "no certificates found\n"); goto failed; } /* use the first cert */ authcert=&certs[0]; /* get random bytes */ random = OPENSSL_malloc(RANDOM_SIZE); if (random == NULL) goto failed; fd = open(RANDOM_SOURCE, O_RDONLY); if (fd < 0) { fprintf(stderr, "fatal: cannot open RANDOM_SOURCE: %s\n", strerror(errno)); goto failed; } rc = read(fd, random, RANDOM_SIZE); if (rc < 0) { fprintf(stderr, "fatal: read from random source failed: %s\n", strerror(errno)); close(fd); goto failed; } if (rc < RANDOM_SIZE) { fprintf(stderr, "fatal: read returned less than %d<%d bytes\n", rc, RANDOM_SIZE); close(fd); goto failed; } close(fd); authkey = PKCS11_find_key(authcert); if (authkey == NULL) { fprintf(stderr, "no key matching certificate available\n"); goto failed; } /* ask for a sha1 hash of the random data, signed by the key */ siglen = MAX_SIGSIZE; signature = OPENSSL_malloc(MAX_SIGSIZE); if (signature == NULL) goto failed; rc = PKCS11_sign(NID_sha1, random, RANDOM_SIZE, signature, &siglen, authkey); if (rc != 1) { fprintf(stderr, "fatal: pkcs11_sign failed\n"); goto failed; } /* verify the signature */ pubkey = X509_get_pubkey(authcert->x509); if (pubkey == NULL) { fprintf(stderr, "could not extract public key\n"); goto failed; } /* now verify the result */ rc = RSA_verify(NID_sha1, random, RANDOM_SIZE, signature, siglen, pubkey->pkey.rsa); if (rc != 1) { fprintf(stderr, "fatal: RSA_verify failed\n"); goto failed; } if (pubkey != NULL) EVP_PKEY_free(pubkey); if (random != NULL) OPENSSL_free(random); if (signature != NULL) OPENSSL_free(signature); PKCS11_release_all_slots(ctx, slots, nslots); PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); printf("authentication successfull.\n"); return 0; failed: ERR_print_errors_fp(stderr); notoken: PKCS11_release_all_slots(ctx, slots, nslots); noslots: PKCS11_CTX_unload(ctx); nolib: PKCS11_CTX_free(ctx); printf("authentication failed.\n"); return 1; } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/examples/decrypt.c000066400000000000000000000124751265040137300173370ustar00rootroot00000000000000/* libp11 example code: auth.c * * This examply simply connects to your smart card * and does a public key authentication. * * Feel free to copy all of the code as needed. * */ #include #include #include #include #include #include #include #include #define RANDOM_SOURCE "/dev/urandom" #define RANDOM_SIZE 64 #define MAX_SIGSIZE 256 int main(int argc, char *argv[]) { PKCS11_CTX *ctx; PKCS11_SLOT *slots, *slot; PKCS11_CERT *certs; PKCS11_KEY *authkey; PKCS11_CERT *authcert; EVP_PKEY *pubkey = NULL; unsigned char *random = NULL, *encrypted = NULL, *decrypted = NULL; char password[20]; int rc = 0, fd, len; unsigned int nslots, ncerts; if (argc != 2) { fprintf(stderr, "usage: auth /usr/lib/opensc-pkcs11.so\n"); return 1; } ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(ctx, argv[1]); if (rc) { fprintf(stderr, "loading pkcs11 engine failed: %s\n", ERR_reason_error_string(ERR_get_error())); rc = 1; goto nolib; } /* get information on all slots */ rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); if (rc < 0) { fprintf(stderr, "no slots available\n"); rc = 2; goto noslots; } /* get first slot with a token */ slot = PKCS11_find_token(ctx, slots, nslots); if (slot == NULL || slot->token == NULL) { fprintf(stderr, "no token available\n"); rc = 3; goto notoken; } printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); /* get all certs */ rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts); if (rc) { fprintf(stderr, "PKCS11_enumerate_certs failed\n"); goto failed; } if (ncerts <= 0) { fprintf(stderr, "no certificates found\n"); goto failed; } /* use the first cert */ authcert=&certs[0]; /* get random bytes */ random = OPENSSL_malloc(RANDOM_SIZE); if (random == NULL) goto failed; fd = open(RANDOM_SOURCE, O_RDONLY); if (fd < 0) { fprintf(stderr, "fatal: cannot open RANDOM_SOURCE: %s\n", strerror(errno)); goto failed; } rc = read(fd, random, RANDOM_SIZE); if (rc < 0) { fprintf(stderr, "fatal: read from random source failed: %s\n", strerror(errno)); close(fd); goto failed; } if (rc < RANDOM_SIZE) { fprintf(stderr, "fatal: read returned less than %d<%d bytes\n", rc, RANDOM_SIZE); close(fd); goto failed; } close(fd); /* get RSA key */ pubkey = X509_get_pubkey(authcert->x509); if (pubkey == NULL) { fprintf(stderr, "could not extract public key\n"); goto failed; } /* allocate destination buffer */ encrypted = OPENSSL_malloc(RSA_size(pubkey->pkey.rsa)); if (encrypted == NULL) { fprintf(stderr,"out of memory for encrypted data"); goto failed; } /* use public key for encryption */ len = RSA_public_encrypt(RANDOM_SIZE, random, encrypted, pubkey->pkey.rsa, RSA_PKCS1_PADDING); if (len < 0) { fprintf(stderr, "fatal: RSA_public_encrypt failed\n"); goto failed; } /* now decrypt */ if (!slot->token->loginRequired) goto loggedin; /* get password */ struct termios old, new; /* Turn echoing off and fail if we can't. */ if (tcgetattr(0, &old) != 0) goto failed; new = old; new.c_lflag &= ~ECHO; if (tcsetattr(0, TCSAFLUSH, &new) != 0) goto failed; /* Read the password. */ printf("Password for token %.32s: ", slot->token->label); if (fgets(password, sizeof(password), stdin) == NULL) goto failed; /* Restore terminal. */ (void)tcsetattr(0, TCSAFLUSH, &old); /* strip tailing \n from password */ rc = strlen(password); if (rc <= 0) goto failed; password[rc-1]=0; /* perform pkcs #11 login */ rc = PKCS11_login(slot, 0, password); memset(password, 0, strlen(password)); if (rc != 0) { fprintf(stderr, "PKCS11_login failed\n"); goto failed; } loggedin: authkey = PKCS11_find_key(authcert); if (authkey == NULL) { fprintf(stderr, "no key matching certificate available\n"); goto failed; } /* allocate space for decrypted data */ decrypted = OPENSSL_malloc(RSA_size(pubkey->pkey.rsa)); if (decrypted == NULL) goto failed; rc = PKCS11_private_decrypt(len, encrypted, decrypted, authkey, RSA_PKCS1_PADDING); if (rc != RANDOM_SIZE) { fprintf(stderr, "fatal: PKCS11_private_decrypt failed\n"); goto failed; } /* check if original matches decypted */ if (memcmp(random, decrypted, RANDOM_SIZE) != 0) { fprintf(stderr, "fatal: decrypted data does not match original\n"); goto failed; } PKCS11_release_all_slots(ctx, slots, nslots); PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); if (pubkey != NULL) EVP_PKEY_free(pubkey); if (random != NULL) OPENSSL_free(random); if (encrypted != NULL) OPENSSL_free(encrypted); if (decrypted != NULL) OPENSSL_free(decrypted); CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); ERR_remove_state(0); printf("decryption successfull.\n"); return 0; failed: ERR_print_errors_fp(stderr); notoken: PKCS11_release_all_slots(ctx, slots, nslots); noslots: PKCS11_CTX_unload(ctx); nolib: PKCS11_CTX_free(ctx); printf("decryption failed.\n"); return 1; } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/examples/getrandom.c000066400000000000000000000040421265040137300176340ustar00rootroot00000000000000/* libp11 example code: getrandom.c * * This examply simply connects to your smart card and * asks for a few random bytes. * * Feel free to copy all of the code as needed. * */ #include #include int main(int argc, char *argv[]) { PKCS11_CTX *ctx; PKCS11_SLOT *slots, *slot; unsigned char random[10]; int rc = 0, i, len; unsigned int nslots; if (argc != 2) { fprintf(stderr, "usage: getrandom /usr/lib/opensc-pkcs11.so\n"); return 1; } /* new context */ ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(ctx, argv[1]); if (rc) { fprintf(stderr, "loading pkcs11 engine failed: %s\n", ERR_reason_error_string(ERR_get_error())); rc = 1; goto nolib; } /* get information on all slots */ rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); if (rc < 0) { fprintf(stderr, "no slots available\n"); rc = 2; goto noslots; } printf("%d slots available\n", nslots); /* get first slot with a token */ slot = PKCS11_find_token(ctx, slots, nslots); if (slot == NULL || slot->token == NULL) { fprintf(stderr, "no token available\n"); rc = 3; goto notoken; } printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); /* get 10 random bytes */ len = sizeof(random); rc = PKCS11_generate_random(slot, random, len); if (rc < 0) { fprintf(stderr, "generate_random failed: %s\n", ERR_reason_error_string(ERR_get_error())); rc = 4; goto norandom; } printf("\nRandom numbers generated by the token: "); for (i = 0; i < len; i++) printf("%02X ", random[i]); printf("\n"); rc = 0; norandom: notoken: PKCS11_release_all_slots(ctx, slots, nslots); noslots: PKCS11_CTX_unload(ctx); nolib: PKCS11_CTX_free(ctx); return rc; } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/examples/listkeys.c000066400000000000000000000067511265040137300175340ustar00rootroot00000000000000/* libp11 example code: listkeys.c * * This examply simply connects to your smart card * and list the keys. * * Feel free to copy all of the code as needed. * */ #include #include #include #include #include #include #include #include #include #include #include #define RANDOM_SOURCE "/dev/urandom" #define RANDOM_SIZE 20 #define MAX_SIGSIZE 256 static void list_keys(const char *title, const PKCS11_KEY *keys, const unsigned int nkeys); static void error_queue(const char *name); #define CHECK_ERR(cond, txt, code) \ do { \ if (cond) { \ fprintf(stderr, "%s\n", (txt)); \ rc=(code); \ goto end; \ } \ } while (0) int main(int argc, char *argv[]) { PKCS11_CTX *ctx=NULL; PKCS11_SLOT *slots=NULL, *slot; PKCS11_KEY *keys; unsigned int nslots, nkeys; char password[20]; int rc = 0; if (argc < 2) { fprintf(stderr, "usage: %s /usr/lib/opensc-pkcs11.so [PIN]\n", argv[0]); return 1; } ctx = PKCS11_CTX_new(); error_queue("PKCS11_CTX_new"); /* load pkcs #11 module */ rc = PKCS11_CTX_load(ctx, argv[1]); error_queue("PKCS11_CTX_load"); CHECK_ERR(rc < 0, "loading pkcs11 engine failed", 1); /* get information on all slots */ rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); error_queue("PKCS11_enumerate_slots"); CHECK_ERR(rc < 0, "no slots available", 2); /* get first slot with a token */ slot = PKCS11_find_token(ctx, slots, nslots); error_queue("PKCS11_find_token"); CHECK_ERR(!slot || !slot->token, "no token available", 3); printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); /* get public keys */ rc = PKCS11_enumerate_public_keys(slot->token, &keys, &nkeys); error_queue("PKCS11_enumerate_public_keys"); CHECK_ERR(rc < 0, "PKCS11_enumerate_public_keys failed", 4); CHECK_ERR(nkeys == 0, "No public keys found", 5); list_keys("Public keys", keys, nkeys); if (slot->token->loginRequired && argc > 2) { strcpy(password, argv[2]); /* perform pkcs #11 login */ rc = PKCS11_login(slot, 0, password); error_queue("PKCS11_login"); memset(password, 0, strlen(password)); CHECK_ERR(rc < 0, "PKCS11_login failed", 6); } /* get private keys */ rc = PKCS11_enumerate_keys(slot->token, &keys, &nkeys); error_queue("PKCS11_enumerate_keys"); CHECK_ERR(rc < 0, "PKCS11_enumerate_keys failed", 7); CHECK_ERR(nkeys == 0, "No private keys found", 8); list_keys("Private keys", keys, nkeys); end: if (slots) PKCS11_release_all_slots(ctx, slots, nslots); if (ctx) { PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); } CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); if (rc) printf("Failed (error code %d).\n", rc); else printf("Success.\n"); return rc; } static void list_keys(const char *title, const PKCS11_KEY *keys, const unsigned int nkeys) { unsigned int i; printf("\n%s:\n", title); for (i = 0; i < nkeys; i++) printf(" * %s key: %s\n", keys[i].isPrivate ? "Private" : "Public", keys[i].label); } static void error_queue(const char *name) { if (ERR_peek_last_error()) { fprintf(stderr, "%s generated errors:\n", name); ERR_print_errors_fp(stderr); } } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/examples/rawrsasign.c000066400000000000000000000164621265040137300200450ustar00rootroot00000000000000/* libp11 example code: rawrsasign.c * * This example simply connects to your smart card * and demonstrate how to do a raw RSA signing operation with it. * * WARNING: Raw RSA signing *is insecure* and should not be * done without proper padding done elsewhere. * So far, PKCS11_private_encrypt() can only manage PKCS1 padding * and using it with no padding is usefull when padding is * to be done by the software. * This allows to use other padding schemes (like RSA-PSS) * with smart cards, without requiring padding to be done by * the smart card itself. * * Feel free to copy all of the code as needed. * */ #include #include #include #include #include #include #include #include #include #include #include #include #define RANDOM_SOURCE "/dev/urandom" #define RANDOM_SIZE 100 #define MAX_SIGSIZE 256 /* Should be adapted to the used RSA key size */ #define END(x) do { ret = (x); goto end; } while (0) int main(int argc, char *argv[]) { PKCS11_CTX *ctx = NULL; PKCS11_SLOT *slots = NULL, *slot = NULL; PKCS11_CERT *certs = NULL; PKCS11_KEY *authkey = NULL; PKCS11_CERT *authcert = NULL; EVP_PKEY *pubkey = NULL; EVP_MD_CTX mctx; EVP_PKEY_CTX *pkeyctx = NULL; unsigned char *random = NULL, *signature = NULL; char password[20]; int rc = 0, fd; unsigned int nslots, ncerts, siglen; static unsigned char hash[EVP_MAX_MD_SIZE]; static unsigned char enc[MAX_SIGSIZE]; static unsigned char pad[MAX_SIGSIZE]; unsigned int plen = MAX_SIGSIZE; unsigned int elen = 0; unsigned int hlen = 0; unsigned char* p; X509_SIG sig; ASN1_TYPE parameter; X509_ALGOR algorithm; ASN1_OCTET_STRING digest; int ret; if (argc < 2) { fprintf(stderr, "usage: auth /usr/lib/opensc-pkcs11.so [PIN]\n"); END(1); } ctx = PKCS11_CTX_new(); /* load pkcs #11 module */ rc = PKCS11_CTX_load(ctx, argv[1]); if (rc) { fprintf(stderr, "loading pkcs11 engine failed: %s\n", ERR_reason_error_string(ERR_get_error())); END(1); } /* get information on all slots */ rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); if (rc < 0) { fprintf(stderr, "no slots available\n"); END(1); } /* get first slot with a token */ slot = PKCS11_find_token(ctx, slots, nslots); if (slot == NULL || slot->token == NULL) { fprintf(stderr, "no token available\n"); END(1); } printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); if (!slot->token->loginRequired) goto loggedin; /* get password */ if (argc > 2) { strcpy(password, argv[2]); } else { struct termios old, new; /* Turn echoing off and fail if we can't. */ if (tcgetattr(0, &old) != 0) END(1); new = old; new.c_lflag &= ~ECHO; if (tcsetattr(0, TCSAFLUSH, &new) != 0) END(1); /* Read the password. */ printf("Password for token %.32s: ", slot->token->label); if (fgets(password, sizeof(password), stdin) == NULL) END(1); /* Restore terminal. */ (void)tcsetattr(0, TCSAFLUSH, &old); /* strip tailing \n from password */ rc = strlen(password); if (rc <= 0) END(1); password[rc-1]=0; } loggedin: /* perform pkcs #11 login */ rc = PKCS11_login(slot, 0, password); memset(password, 0, strlen(password)); if (rc != 0) { fprintf(stderr, "PKCS11_login failed\n"); END(1); } /* get all certs */ rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts); if (rc) { fprintf(stderr, "PKCS11_enumerate_certs failed\n"); END(1); } if (ncerts <= 0) { fprintf(stderr, "no certificates found\n"); END(1); } /* use the first cert */ authcert=&certs[0]; /* get random bytes */ random = OPENSSL_malloc(RANDOM_SIZE); if (random == NULL) END(1); fd = open(RANDOM_SOURCE, O_RDONLY); if (fd < 0) { fprintf(stderr, "fatal: cannot open RANDOM_SOURCE: %s\n", strerror(errno)); END(1); } rc = read(fd, random, RANDOM_SIZE); if (rc < 0) { fprintf(stderr, "fatal: read from random source failed: %s\n", strerror(errno)); close(fd); END(1); } if (rc < RANDOM_SIZE) { fprintf(stderr, "fatal: read returned less than %d<%d bytes\n", rc, RANDOM_SIZE); close(fd); END(1); } close(fd); authkey = PKCS11_find_key(authcert); if (authkey == NULL) { fprintf(stderr, "no key matching certificate available\n"); END(1); } /* Compute the SHA1 hash of the random bytes */ EVP_MD_CTX_init(&mctx); if (EVP_DigestInit(&mctx, EVP_sha1()) != 1) { fprintf(stderr, "fatal: EVP_DigestInit failed\n"); END(1); } if (EVP_DigestUpdate(&mctx, random, RANDOM_SIZE) != 1) { fprintf(stderr, "fatal: EVP_DigestUpdate failed\n"); END(1); } if (EVP_DigestFinal(&mctx, hash, &hlen) != 1) { fprintf(stderr, "fatal: EVP_DigestFinal failed\n"); END(1); } /* Compute a PKCS #1 "block type 01" encryption-block */ sig.algor = &algorithm; algorithm.algorithm = OBJ_nid2obj(NID_sha1); parameter.type = V_ASN1_NULL; parameter.value.ptr = NULL; algorithm.parameter = ¶meter; sig.digest = &digest; sig.digest->data = hash; sig.digest->length = hlen; p = enc; elen = i2d_X509_SIG(&sig, &p); p = enc; /* Compute PKCS #1 v1.5 padding */ if (RSA_padding_add_PKCS1_type_1(pad, plen, p, elen) != 1) { fprintf(stderr, "fatal: RSA_padding_add_PKCS1_type_1 failed\n"); END(1); } siglen = MAX_SIGSIZE; signature = OPENSSL_malloc(MAX_SIGSIZE); if (signature == NULL) END(1); /* Do a raw RSA sign operation with the smart card */ rc = PKCS11_private_encrypt(plen, pad, signature, authkey, RSA_NO_PADDING); if (rc < 0) { fprintf(stderr, "PKCS11_private_encrypt failed\n"); END(1); } /* Verify the signature */ /* As we have done a PKCS#1 complient padding, we can verify the signature * with "standard code", using openssl EVP interface. */ pubkey = X509_get_pubkey(authcert->x509); if (pubkey == NULL) { fprintf(stderr, "could not extract public key\n"); END(1); } EVP_MD_CTX_init(&mctx); if (EVP_DigestVerifyInit(&mctx, &pkeyctx, EVP_sha1(), NULL, pubkey) != 1) { fprintf(stderr, "fatal: EVP_DigestVerifyInit failed\n"); END(1); } if (EVP_PKEY_CTX_set_rsa_padding(pkeyctx, RSA_PKCS1_PADDING) <= 0) { fprintf(stderr, "fatal: EVP_PKEY_CTX_set_rsa_padding failed\n"); END(1); } if (EVP_DigestVerifyUpdate(&mctx, (const void*)random, RANDOM_SIZE) <= 0) { fprintf(stderr, "fatal: EVP_DigestVerifyUpdate failed\n"); END(1); } if ((rc = EVP_DigestVerifyFinal(&mctx, signature, siglen)) != 1) { fprintf(stderr, "fatal: EVP_DigestVerifyFinal failed : %d\n", rc); END(1); } printf("raw signing operation and signature verification successfull.\n"); ret = 0; end: if (ret != 0) { ERR_print_errors_fp(stderr); printf("raw signing operation failed.\n"); } if (pubkey != NULL) EVP_PKEY_free(pubkey); if (random != NULL) OPENSSL_free(random); if (signature != NULL) OPENSSL_free(signature); if (slots != NULL) PKCS11_release_all_slots(ctx, slots, nslots); if ( ctx != NULL ) { PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); } CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); return ret; } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/m4/000077500000000000000000000000001265040137300142125ustar00rootroot00000000000000libp11-libp11-0.3.1/m4/.keep000066400000000000000000000000001265040137300151250ustar00rootroot00000000000000libp11-libp11-0.3.1/make.rules.mak000066400000000000000000000020101265040137300164230ustar00rootroot00000000000000#define OPENSSL_STATIC if you have visual studio compatible with OpenSSL's static binaries #OPENSSL_STATIC_DIR = static !IF "$(DEBUG)" != "" DEBUG_SUFFIX = d DEBUG_COMPILE = /DDEBUG /Zi /Od DEBUG_LINK = /DEBUG !ENDIF !IF "$(BUILD_FOR)" == "WIN64" MACHINE = /MACHINE:X64 !IF "$(OPENSSL_DIR)" == "" OPENSSL_DIR = C:\OpenSSL-Win64 !ENDIF !ELSE MACHINE = /MACHINE:X86 !IF "$(OPENSSL_DIR)" == "" OPENSSL_DIR = C:\OpenSSL-Win32 !ENDIF !ENDIF !IF "$(OPENSSL_INC)" == "" OPENSSL_INC = /I$(OPENSSL_DIR)\include !ENDIF !IF "$(OPENSSL_STATIC_DIR)" == "" OPENSSL_LIB = $(OPENSSL_DIR)\lib\libeay32.lib !ELSE OPENSSL_LIB = $(OPENSSL_DIR)\lib\VC\static\libeay32MT$(DEBUG_SUFFIX).lib !ENDIF LIBS = $(OPENSSL_LIB) user32.lib advapi32.lib crypt32.lib gdi32.lib CLFLAGS = /nologo /GS /W3 /D_CRT_SECURE_NO_DEPRECATE /MT$(DEBUG_SUFFIX) $(OPENSSL_INC) /D_WIN32_WINNT=0x0502 /DWIN32_LEAN_AND_MEAN $(DEBUG_COMPILE) LINKFLAGS = /NOLOGO /INCREMENTAL:NO $(MACHINE) /MANIFEST:NO /NXCOMPAT /DYNAMICBASE $(DEBUG_LINK) libp11-libp11-0.3.1/src/000077500000000000000000000000001265040137300144615ustar00rootroot00000000000000libp11-libp11-0.3.1/src/Makefile.am000066400000000000000000000023621265040137300165200ustar00rootroot00000000000000MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/config.h.in $(srcdir)/config.h.in~ CLEANFILES = libp11.pc EXTRA_DIST = Makefile.mak versioninfo.rc.in noinst_HEADERS= libp11-int.h pkcs11.h atfork.h include_HEADERS= libp11.h lib_LTLIBRARIES = libp11.la pkgconfig_DATA = libp11.pc libp11_la_SOURCES = libpkcs11.c p11_attr.c p11_cert.c p11_err.c p11_key.c \ p11_load.c p11_misc.c p11_ops.c p11_rsa.c p11_ec.c p11_slot.c \ libp11.exports atfork.c if WIN32 libp11_la_SOURCES += versioninfo.rc else dist_noinst_DATA = versioninfo.rc endif libp11_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) libp11_la_LIBADD = $(OPENSSL_LIBS) libp11_la_LDFLAGS = $(AM_LDFLAGS) \ -version-info @LIBP11_LT_CURRENT@:@LIBP11_LT_REVISION@:@LIBP11_LT_AGE@ \ -export-symbols "$(srcdir)/libp11.exports" \ -no-undefined if WIN32 # def file required for MS users to build library mylibdir=$(libdir) mylib_DATA=.libs/@WIN_LIBPREFIX@p11-@LIBP11_LT_OLDEST@.dll.def .libs/@WIN_LIBPREFIX@p11-@LIBP11_LT_OLDEST@.dll.def: libp11.la endif RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) .rc.lo: $(LTRCCOMPILE) -i "$<" -o "$@" .rc.o: $(RCCOMPILE) -i "$<" -o "$@" # vim: set noexpandtab: libp11-libp11-0.3.1/src/Makefile.mak000066400000000000000000000012671265040137300166760ustar00rootroot00000000000000TOPDIR = .. !INCLUDE $(TOPDIR)\make.rules.mak TARGET = libp11.dll OBJECTS = libpkcs11.obj p11_attr.obj p11_cert.obj \ p11_err.obj p11_key.obj p11_load.obj p11_misc.obj p11_rsa.obj \ p11_ec.obj p11_slot.obj p11_ops.obj all: $(TARGET) versioninfo.res RSC_PROJ=/l 0x809 /r /fo"versioninfo.res" versioninfo.res: versioninfo.rc rc $(RSC_PROJ) versioninfo.rc .c.obj:: cl $(CLFLAGS) /c $< $(TARGET): $(OBJECTS) versioninfo.res echo LIBRARY $* > $*.def echo EXPORTS >> $*.def type $*.exports >> $*.def link $(LINKFLAGS) /dll /def:$*.def /implib:$*.lib /out:$(TARGET) \ $(OBJECTS) $(LIBS) versioninfo.res if EXIST $*.dll.manifest mt -manifest $*.dll.manifest -outputresource:$*.dll;2 libp11-libp11-0.3.1/src/atfork.c000066400000000000000000000036221265040137300161160ustar00rootroot00000000000000/* * Copyright (C) 2010-2012 Free Software Foundation, Inc. * Copyright (C) 2014 Red Hat * * Author: Nikos Mavrogiannopoulos * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see * */ #include "libp11-int.h" #include #include #include #include #include #include #ifdef __sun # pragma fini(lib_deinit) # pragma init(lib_init) # define _CONSTRUCTOR # define _DESTRUCTOR #else # define _CONSTRUCTOR __attribute__((constructor)) # define _DESTRUCTOR __attribute__((destructor)) #endif unsigned int P11_forkid = 0; #ifndef _WIN32 # ifdef HAVE_ATFORK static void fork_handler(void) { P11_forkid++; } # endif # if defined(HAVE___REGISTER_ATFORK) extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *); extern void *__dso_handle; _CONSTRUCTOR int _P11_register_fork_handler(void) { if (__register_atfork(0, 0, fork_handler, __dso_handle) != 0) return -1; return 0; } # else unsigned int _P11_get_forkid(void) { return getpid(); } int _P11_detect_fork(unsigned int forkid) { if (getpid() == forkid) return 0; return 1; } /* we have to detect fork manually */ _CONSTRUCTOR int _P11_register_fork_handler(void) { P11_forkid = getpid(); return 0; } # endif #endif /* !_WIN32 */ /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/atfork.h000066400000000000000000000026111265040137300161200ustar00rootroot00000000000000/* * Copyright (C) 2014 Red Hat * * Author: Nikos Mavrogiannopoulos * * This file is part of GnuTLS. * * The GnuTLS is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see * */ #ifndef ATFORK_H # define ATFORK_H extern unsigned int P11_forkid; #if defined(HAVE___REGISTER_ATFORK) # define HAVE_ATFORK #endif #ifndef _WIN32 /* API */ int _P11_register_fork_handler(void); /* global init */ # if defined(HAVE_ATFORK) inline static int _P11_detect_fork(unsigned int forkid) { if (forkid == P11_forkid) return 0; return 1; } inline static unsigned int _P11_get_forkid(void) { return P11_forkid; } # else int _P11_detect_fork(unsigned int forkid); unsigned int _P11_get_forkid(void); # endif #else # define _P11_detect_fork(x) 0 # define _P11_get_forkid() 0 #endif #endif /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/libp11-int.h000066400000000000000000000146341265040137300165220ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _LIBP11_INT_H #define _LIBP11_INT_H #ifndef _WIN32 #include "config.h" #endif #include #include #include #define CRYPTOKI_EXPORTS #include "pkcs11.h" extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR); extern CK_RV C_UnloadModule(void *module); #include "libp11.h" #include "atfork.h" /* get private implementations of PKCS11 structures */ /* * PKCS11_CTX: context for a PKCS11 implementation */ typedef struct pkcs11_ctx_private { char *name; void *libinfo; CK_FUNCTION_LIST_PTR method; char *init_args; unsigned int forkid; int lockid; } PKCS11_CTX_private; #define PRIVCTX(ctx) ((PKCS11_CTX_private *) ((ctx)->_private)) int check_fork(PKCS11_CTX *); #define CHECK_FORK(ctx) if (check_fork(ctx) < 0) return -1 typedef struct pkcs11_slot_private { PKCS11_CTX *parent; unsigned char haveSession, loggedIn; CK_SLOT_ID id; CK_SESSION_HANDLE session; unsigned int forkid; int prev_rw; /* the rw status the session was open */ /* options used in last PKCS11_login */ char *prev_pin; int prev_so; /* per-slot lock */ int lockid; } PKCS11_SLOT_private; #define PRIVSLOT(slot) ((PKCS11_SLOT_private *) ((slot)->_private)) #define SLOT2CTX(slot) (PRIVSLOT(slot)->parent) int check_slot_fork(PKCS11_SLOT *); #define CHECK_SLOT_FORK(slot_ctx) if (check_slot_fork(slot_ctx) < 0) return -1 int check_key_fork(PKCS11_KEY *); #define CHECK_KEY_FORK(key) if (check_key_fork(key) < 0) return -1 typedef struct pkcs11_keys { int num; PKCS11_KEY *keys; } PKCS11_keys; typedef struct pkcs11_token_private { PKCS11_SLOT *parent; PKCS11_keys prv, pub; int ncerts; PKCS11_CERT *certs; } PKCS11_TOKEN_private; #define PRIVTOKEN(token) ((PKCS11_TOKEN_private *) ((token)->_private)) #define TOKEN2SLOT(token) (PRIVTOKEN(token)->parent) #define TOKEN2CTX(token) SLOT2CTX(TOKEN2SLOT(token)) typedef struct pkcs11_key_ops { int type; /* EVP_PKEY_xxx */ EVP_PKEY *(*get_evp_key) (PKCS11_KEY *); } PKCS11_KEY_ops; typedef struct pkcs11_key_private { PKCS11_TOKEN *parent; CK_OBJECT_HANDLE object; unsigned char id[255]; size_t id_len; PKCS11_KEY_ops *ops; unsigned int forkid; } PKCS11_KEY_private; #define PRIVKEY(key) ((PKCS11_KEY_private *) (key)->_private) #define KEY2SLOT(key) TOKEN2SLOT(KEY2TOKEN(key)) #define KEY2TOKEN(key) (PRIVKEY(key)->parent) #define KEY2CTX(key) TOKEN2CTX(KEY2TOKEN(key)) typedef struct pkcs11_cert_private { PKCS11_TOKEN *parent; CK_OBJECT_HANDLE object; unsigned char id[255]; size_t id_len; } PKCS11_CERT_private; #define PRIVCERT(cert) ((PKCS11_CERT_private *) (cert)->_private) #define CERT2SLOT(cert) TOKEN2SLOT(CERT2TOKEN(cert)) #define CERT2TOKEN(cert) (PRIVCERT(cert)->parent) #define CERT2CTX(cert) TOKEN2CTX(CERT2TOKEN(cert)) /* * Mapping Cryptoki error codes to those used internally * by this code. * Right now, we just map them directly, and make sure * that the few genuine messages we use don't clash with * PKCS#11 */ #define pkcs11_map_err(rv) (rv) /* * Internal functions */ #define CRYPTOKI_checkerr(f, rv) \ do { \ if (rv) { \ PKCS11err(f, pkcs11_map_err(rv)); \ return -1; \ } \ ERR_clear_error(); \ } while (0) #define CRYPTOKI_call(ctx, func_and_args) \ PRIVCTX(ctx)->method->func_and_args /* Memory allocation */ #define PKCS11_DUP(s) \ pkcs11_strdup((char *) s, sizeof(s)) int pkcs11_get_new_dynlockid(); void pkcs11_destroy_dynlockid(int); #define pkcs11_w_lock(type) \ if(type) CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) #define pkcs11_w_unlock(type) \ if(type) CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) #define pkcs11_r_lock(type) \ if(type) CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) #define pkcs11_r_unlock(type) \ if(type) CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) extern int pkcs11_enumerate_slots(PKCS11_CTX *, PKCS11_SLOT **, unsigned int *); extern void pkcs11_release_slot(PKCS11_CTX *, PKCS11_SLOT *slot); extern void pkcs11_destroy_keys(PKCS11_TOKEN *, unsigned int); extern void pkcs11_destroy_certs(PKCS11_TOKEN *); extern char *pkcs11_strdup(char *, size_t); extern int pkcs11_getattr(PKCS11_TOKEN *, CK_OBJECT_HANDLE, unsigned int, void *, size_t); extern int pkcs11_getattr_s(PKCS11_TOKEN *, CK_OBJECT_HANDLE, unsigned int, void *, size_t); extern int pkcs11_getattr_var(PKCS11_TOKEN *, CK_OBJECT_HANDLE, unsigned int, void *, size_t *); extern int pkcs11_getattr_bn(PKCS11_TOKEN *, CK_OBJECT_HANDLE, unsigned int, BIGNUM **); extern int pkcs11_reload_key(PKCS11_KEY *); #define key_getattr(key, t, p, s) \ pkcs11_getattr(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s)) #define key_getattr_bn(key, t, bn) \ pkcs11_getattr_bn(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (bn)) #define key_getattr_var(key, t, p, s) \ pkcs11_getattr_var(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s)) typedef int (*pkcs11_i2d_fn) (void *, unsigned char **); extern void pkcs11_addattr(CK_ATTRIBUTE_PTR, int, const void *, size_t); extern void pkcs11_addattr_int(CK_ATTRIBUTE_PTR, int, unsigned long); extern void pkcs11_addattr_bool(CK_ATTRIBUTE_PTR, int, int); extern void pkcs11_addattr_s(CK_ATTRIBUTE_PTR, int, const char *); extern void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR, int, const BIGNUM *); extern void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR, int, pkcs11_i2d_fn, void *); extern void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR, unsigned int); extern void *memdup(const void *, size_t); int PKCS11_reopen_session(PKCS11_SLOT * slot); int PKCS11_relogin(PKCS11_SLOT * slot); extern PKCS11_KEY_ops pkcs11_rsa_ops; extern PKCS11_KEY_ops *pkcs11_ec_ops; #endif /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/libp11.exports000066400000000000000000000015201265040137300171750ustar00rootroot00000000000000PKCS11_CTX_init_args PKCS11_CTX_new PKCS11_CTX_load PKCS11_CTX_unload PKCS11_CTX_free PKCS11_open_session PKCS11_enumerate_slots PKCS11_release_all_slots PKCS11_find_token PKCS11_is_logged_in PKCS11_login PKCS11_logout PKCS11_enumerate_keys PKCS11_enumerate_public_keys PKCS11_get_key_type PKCS11_get_key_size PKCS11_get_key_modulus PKCS11_get_key_exponent PKCS11_get_private_key PKCS11_get_public_key PKCS11_get_slotid_from_slot PKCS11_find_certificate PKCS11_find_key PKCS11_enumerate_certs PKCS11_init_token PKCS11_init_pin PKCS11_change_pin PKCS11_generate_key PKCS11_store_private_key PKCS11_store_public_key PKCS11_store_certificate PKCS11_sign PKCS11_private_encrypt PKCS11_private_decrypt PKCS11_verify PKCS11_seed_random PKCS11_generate_random PKCS11_get_rsa_method PKCS11_get_ecdsa_method PKCS11_ecdsa_method_free ERR_load_PKCS11_strings libp11-libp11-0.3.1/src/libp11.h000066400000000000000000000333761265040137300157360ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file libp11.h * @brief libp11 header file */ #ifndef _LIB11_H #define _LIB11_H #include #include #include #ifdef __cplusplus extern "C" { #endif /* get some structures for local code to handle pkcs11 data readily */ #define ERR_LIB_PKCS11 ERR_LIB_USER #define PKCS11err(f,r) \ ERR_PUT_error(ERR_LIB_PKCS11,(f),(r),__FILE__,__LINE__) /* * The purpose of this library is to provide a simple PKCS11 * interface to OpenSSL application that wish to use a previously * initialized card (as opposed to initializing it, etc). * * I am therefore making some simplifying assumptions: * * - no support for any operations that alter the card, * i.e. readonly-login */ /** PKCS11 key object (public or private) */ typedef struct PKCS11_key_st { char *label; unsigned char *id; size_t id_len; unsigned char isPrivate; /**< private key present? */ unsigned char needLogin; /**< login to read private key? */ EVP_PKEY *evp_key; /**< initially NULL, need to call PKCS11_load_key */ void *_private; } PKCS11_KEY; /** PKCS11 certificate object */ typedef struct PKCS11_cert_st { char *label; unsigned char *id; size_t id_len; X509 *x509; void *_private; } PKCS11_CERT; /** PKCS11 token: smart card or USB key */ typedef struct PKCS11_token_st { char *label; char *manufacturer; char *model; char *serialnr; unsigned char initialized; unsigned char loginRequired; unsigned char secureLogin; unsigned char userPinSet; unsigned char readOnly; unsigned char hasRng; unsigned char userPinCountLow; unsigned char userPinFinalTry; unsigned char userPinLocked; unsigned char userPinToBeChanged; unsigned char soPinCountLow; unsigned char soPinFinalTry; unsigned char soPinLocked; unsigned char soPinToBeChanged; void *_private; } PKCS11_TOKEN; /** PKCS11 slot: card reader */ typedef struct PKCS11_slot_st { char *manufacturer; char *description; unsigned char removable; PKCS11_TOKEN *token; /**< NULL if no token present */ void *_private; } PKCS11_SLOT; /** PKCS11 context */ typedef struct PKCS11_ctx_st { char *manufacturer; char *description; void *_private; } PKCS11_CTX; /** * Create a new libp11 context * * This should be the first function called in the use of libp11 * @return an allocated context */ extern PKCS11_CTX *PKCS11_CTX_new(void); /** * Specify any private PKCS#11 module initializtion args, if necessary * * @return none */ extern void PKCS11_CTX_init_args(PKCS11_CTX * ctx, const char * init_args); /** * Load a PKCS#11 module * * @param ctx context allocated by PKCS11_CTX_new() * @param ident PKCS#11 library filename * @retval 0 success * @retval -1 error */ extern int PKCS11_CTX_load(PKCS11_CTX * ctx, const char * ident); /** * Reinitialize a PKCS#11 module (after a fork) * * @param ctx context allocated by PKCS11_CTX_new() * @retval 0 success * @retval -1 error */ extern int PKCS11_CTX_reload(PKCS11_CTX * ctx); /** * Unload a PKCS#11 module * * @param ctx context allocated by PKCS11_CTX_new() */ extern void PKCS11_CTX_unload(PKCS11_CTX * ctx); /** * Free a libp11 context * * @param ctx context allocated by PKCS11_CTX_new() */ extern void PKCS11_CTX_free(PKCS11_CTX * ctx); /** Open a session in RO or RW mode * * @param slot slot descriptor returned by PKCS11_find_token() or PKCS11_enumerate_slots() * @param rw open in read/write mode is mode != 0, otherwise in read only mode * @retval 0 success * @retval -1 error */ extern int PKCS11_open_session(PKCS11_SLOT * slot, int rw); /** * Get a list of all slots * * @param ctx context allocated by PKCS11_CTX_new() * @param slotsp pointer on a list of slots * @param nslotsp size of the allocated list * @retval 0 success * @retval -1 error */ extern int PKCS11_enumerate_slots(PKCS11_CTX * ctx, PKCS11_SLOT **slotsp, unsigned int *nslotsp); /** * Get the slot_id from a slot as it is stored in private * * @param slotp pointer on a slot * @retval the slotid */ extern unsigned long PKCS11_get_slotid_from_slot(PKCS11_SLOT *slotp); /** * Free the list of slots allocated by PKCS11_enumerate_slots() * * @param ctx context allocated by PKCS11_CTX_new() * @param slots list of slots allocated by PKCS11_enumerate_slots() * @param nslots size of the list */ extern void PKCS11_release_all_slots(PKCS11_CTX * ctx, PKCS11_SLOT *slots, unsigned int nslots); /** * Find the first slot with a token * * @param ctx context allocated by PKCS11_CTX_new() * @param slots list of slots allocated by PKCS11_enumerate_slots() * @param nslots size of the list * @retval !=NULL pointer on a slot structure * @retval NULL error */ PKCS11_SLOT *PKCS11_find_token(PKCS11_CTX * ctx, PKCS11_SLOT *slots, unsigned int nslots); /** * Check if user is already authenticated to a card * * @param slot slot returned by PKCS11_find_token() * @param so kind of login to check: CKU_SO if != 0, otherwise CKU_USER * @param res pointer to return value: 1 if logged in, 0 if not logged in * @retval 0 success * @retval -1 error */ extern int PKCS11_is_logged_in(PKCS11_SLOT * slot, int so, int * res); /** * Authenticate to the card * * @param slot slot returned by PKCS11_find_token() * @param so login as CKU_SO if != 0, otherwise login as CKU_USER * @param pin PIN value * @retval 0 success * @retval -1 error */ extern int PKCS11_login(PKCS11_SLOT * slot, int so, const char *pin); /** * De-authenticate from the card * * @param slot slot returned by PKCS11_find_token() * @retval 0 success * @retval -1 error */ extern int PKCS11_logout(PKCS11_SLOT * slot); /* Get a list of private keys associated with this token */ extern int PKCS11_enumerate_keys(PKCS11_TOKEN *, PKCS11_KEY **, unsigned int *); /* Get a list of public keys associated with this token */ extern int PKCS11_enumerate_public_keys(PKCS11_TOKEN *, PKCS11_KEY **, unsigned int *); /* Get the key type (as EVP_PKEY_XXX) */ extern int PKCS11_get_key_type(PKCS11_KEY *); /* Get size of key modulus in number of bytes */ extern int PKCS11_get_key_size(const PKCS11_KEY *); /* Get actual modules and public exponent as BIGNUM */ extern int PKCS11_get_key_modulus(PKCS11_KEY *, BIGNUM **); extern int PKCS11_get_key_exponent(PKCS11_KEY *, BIGNUM **); /* Get the enveloped private key */ /** * Returns a EVP_PKEY object for the private key * * @param key PKCS11_KEY object * @retval !=NULL reference to EVP_PKEY object. * The returned EVP_PKEY object should be treated as const * and must not be freed. * @retval NULL error */ extern EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY *key); /** * Returns a EVP_PKEY object with the public key * * @param key PKCS11_KEY object * @retval !=NULL reference to EVP_PKEY object. * The returned EVP_PKEY object should be treated as const * and must not be freed. * @retval NULL error */ extern EVP_PKEY *PKCS11_get_public_key(PKCS11_KEY *key); /* Find the corresponding certificate (if any) */ extern PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY *); /* Find the corresponding key (if any) */ extern PKCS11_KEY *PKCS11_find_key(PKCS11_CERT *); /* Find the corresponding key (if any) pub <-> priv base on ID */ extern PKCS11_KEY *PKCS11_find_key_from_key(PKCS11_KEY *); /* Get a list of all certificates associated with this token */ extern int PKCS11_enumerate_certs(PKCS11_TOKEN *, PKCS11_CERT **, unsigned int *); /** * Initialize a token * * @param token token descriptor (in general slot->token) * @param pin Security Officer PIN value * @param label new name of the token * @retval 0 success * @retval -1 error */ extern int PKCS11_init_token(PKCS11_TOKEN * token, const char *pin, const char *label); /** * Initialize the user PIN on a token * * @param token token descriptor (in general slot->token) * @param pin new user PIN value * @retval 0 success * @retval -1 error */ extern int PKCS11_init_pin(PKCS11_TOKEN * token, const char *pin); /** * Change the user PIN on a token * * @param slot slot returned by PKCS11_find_token() * @param old_pin old PIN value * @param new_pin new PIN value * @retval 0 success * @retval -1 error */ extern int PKCS11_change_pin(PKCS11_SLOT * slot, const char *old_pin, const char *new_pin); /** * Generate and store a private key on the token * * @param token token returned by PKCS11_find_token() * @param algorithm EVP_PKEY_RSA * @param bits size of the modulus in bits * @param label label for this key * @param id bytes to use as id value * @param id_len length of id value. * @retval 0 success * @retval -1 error */ extern int PKCS11_generate_key(PKCS11_TOKEN * token, int algorithm, unsigned int bits, char *label, unsigned char* id, size_t id_len); /** * Store private key on a token * * @param token token returned by PKCS11_find_token() * @param pk private key * @param label label for this key * @param id bytes to use as id value * @param id_len length of id value. * @retval 0 success * @retval -1 error */ extern int PKCS11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len); /** * Store public key on a token * * @param token token returned by PKCS11_find_token() * @param pk private key * @param label label for this key * @param id bytes to use as id value * @param id_len length of id value. * @retval 0 success * @retval -1 error */ extern int PKCS11_store_public_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len); /** * Store certificate on a token * * @param token token returned by PKCS11_find_token() * @param x509 x509 certificate object * @param label label for this certificate * @param id bytes to use as id value * @param id_len length of id value. * @param ret_cert put new PKCS11_CERT object here * @retval 0 success * @retval -1 error */ extern int PKCS11_store_certificate(PKCS11_TOKEN * token, X509 * x509, char *label, unsigned char *id, size_t id_len, PKCS11_CERT **ret_cert); /* ec private key operations */ extern int PKCS11_ecdsa_sign(const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, PKCS11_KEY * key); /* rsa private key operations */ extern int PKCS11_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, PKCS11_KEY * key); extern int PKCS11_private_encrypt(int flen, const unsigned char *from, unsigned char *to, PKCS11_KEY * rsa, int padding); /** * Decrypts data using the private key * * @param flen length of the encrypted data * @param from encrypted data * @param to output buffer (MUST be a least flen bytes long) * @param key private key object * @param padding padding algorithm to be used * @return the length of the decrypted data or 0 if an error occurred */ extern int PKCS11_private_decrypt(int flen, const unsigned char *from, unsigned char *to, PKCS11_KEY * key, int padding); extern int PKCS11_verify(int type, const unsigned char *m, unsigned int m_len, unsigned char *signature, unsigned int siglen, PKCS11_KEY * key); /* access random number generator */ extern int PKCS11_seed_random(PKCS11_SLOT *, const unsigned char *s, unsigned int s_len); extern int PKCS11_generate_random(PKCS11_SLOT *, unsigned char *r, unsigned int r_len); /* using with openssl method mechanism */ RSA_METHOD *PKCS11_get_rsa_method(void); ECDSA_METHOD *PKCS11_get_ecdsa_method(void); void PKCS11_ecdsa_method_free(void); /** * Load PKCS11 error strings * * Call this function to be able to use ERR_reason_error_string(ERR_get_error()) * to get an textual version of the latest error code */ extern void ERR_load_PKCS11_strings(void); /* * Function and reason codes */ #define PKCS11_F_PKCS11_CTX_LOAD 1 #define PKCS11_F_PKCS11_ENUM_SLOTS 2 #define PKCS11_F_PKCS11_CHECK_TOKEN 3 #define PKCS11_F_PKCS11_OPEN_SESSION 4 #define PKCS11_F_PKCS11_LOGIN 5 #define PKCS11_F_PKCS11_ENUM_KEYS 6 #define PKCS11_F_PKCS11_GET_KEY 7 #define PKCS11_F_PKCS11_RSA_DECRYPT 8 #define PKCS11_F_PKCS11_RSA_ENCRYPT 9 #define PKCS11_F_PKCS11_RSA_SIGN 10 #define PKCS11_F_PKCS11_RSA_VERIFY 11 #define PKCS11_F_PKCS11_ENUM_CERTS 12 #define PKCS11_F_PKCS11_INIT_TOKEN 13 #define PKCS11_F_PKCS11_INIT_PIN 14 #define PKCS11_F_PKCS11_LOGOUT 15 #define PKCS11_F_PKCS11_STORE_PRIVATE_KEY 16 #define PKCS11_F_PKCS11_GENERATE_KEY 17 #define PKCS11_F_PKCS11_STORE_PUBLIC_KEY 18 #define PKCS11_F_PKCS11_STORE_CERTIFICATE 19 #define PKCS11_F_PKCS11_SEED_RANDOM 20 #define PKCS11_F_PKCS11_GENERATE_RANDOM 21 #define PKCS11_F_PKCS11_CHANGE_PIN 22 #define PKCS11_F_PKCS11_GETATTR 40 #define PKCS11_F_PKCS11_EC_KEY_SIGN 41 #define PKCS11_F_PKCS11_EC_KEY_VERIFY 42 #define PKCS11_F_PKCS11_GETSESSIONINFO 43 #define PKCS11_ERR_BASE 1024 #define PKCS11_LOAD_MODULE_ERROR (PKCS11_ERR_BASE+1) #define PKCS11_MODULE_LOADED_ERROR (PKCS11_ERR_BASE+2) #define PKCS11_SYMBOL_NOT_FOUND_ERROR (PKCS11_ERR_BASE+3) #define PKCS11_NOT_SUPPORTED (PKCS11_ERR_BASE+4) #define PKCS11_NO_SESSION (PKCS11_ERR_BASE+5) #define PKCS11_KEYGEN_FAILED (PKCS11_ERR_BASE+6) #ifdef __cplusplus } #endif #endif /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/libp11.pc.in000066400000000000000000000003171265040137300165030ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libp11 Description: libp11 Version: @VERSION@ Libs: -L${libdir} -lp11 Libs.private: -lcrypto Cflags: -I${includedir} libp11-libp11-0.3.1/src/libpkcs11.c000066400000000000000000000055071265040137300164250ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Convenience pkcs11 library that can be linked into an application, * and will bind to a specific pkcs11 module. * * Copyright (C) 2002 Olaf Kirch */ #include "libp11-int.h" #include #include #include #ifdef _WIN32 #include #else #include #endif #define MAGIC 0xd00bed00 struct sc_pkcs11_module { unsigned int _magic; void *handle; }; typedef struct sc_pkcs11_module sc_pkcs11_module_t; /* * Load a module - this will load the shared object, call * C_Initialize, and get the list of function pointers */ void * C_LoadModule(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs) { sc_pkcs11_module_t *mod; CK_RV (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR); int rv; if (mspec == NULL) return NULL; mod = OPENSSL_malloc(sizeof(sc_pkcs11_module_t)); if (mod == NULL) return NULL; memset(mod, 0, sizeof(sc_pkcs11_module_t)); mod->_magic = MAGIC; #ifdef WIN32 mod->handle = LoadLibraryA(mspec); #else mod->handle = dlopen(mspec, RTLD_NOW); #endif if (mod->handle == NULL) goto failed; #ifdef WIN32 c_get_function_list = (CK_C_GetFunctionList) GetProcAddress(mod->handle, "C_GetFunctionList"); #else { /* * Make compiler happy! */ void *p = dlsym(mod->handle, "C_GetFunctionList"); memmove(&c_get_function_list, &p, sizeof(void *)); } #endif if (c_get_function_list == NULL) goto failed; rv = c_get_function_list(funcs); if (rv == CKR_OK) return mod; failed: C_UnloadModule((void *) mod); return NULL; } /* * Unload a pkcs11 module. * The calling application is responsible for cleaning up * and calling C_Finalize */ CK_RV C_UnloadModule(void *module) { sc_pkcs11_module_t *mod = (sc_pkcs11_module_t *) module; if (mod == NULL || mod->_magic != MAGIC) return CKR_ARGUMENTS_BAD; if (mod->handle) { #ifdef WIN32 FreeLibrary(mod->handle); #else dlclose(mod->handle); #endif } memset(mod, 0, sizeof(sc_pkcs11_module_t)); OPENSSL_free(mod); return CKR_OK; } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/p11_attr.c000066400000000000000000000105531265040137300162640ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * PKCS11 attribute querying. * * The number of layers we stack on top of each other here * is frightening. * * Copyright (C) 2002, Olaf Kirch */ #include "libp11-int.h" #include #include /* * Query pkcs11 attributes */ static int pkcs11_getattr_int(PKCS11_CTX * ctx, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o, CK_ATTRIBUTE_TYPE type, void *value, size_t * size) { CK_ATTRIBUTE templ; int rv; templ.type = type; templ.pValue = value; templ.ulValueLen = *size; rv = CRYPTOKI_call(ctx, C_GetAttributeValue(session, o, &templ, 1)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_GETATTR, rv); *size = templ.ulValueLen; return 0; } int pkcs11_getattr_var(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object, unsigned int type, void *value, size_t * size) { return pkcs11_getattr_int(TOKEN2CTX(token), PRIVSLOT(TOKEN2SLOT(token))->session, object, type, value, size); } int pkcs11_getattr(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object, unsigned int type, void *value, size_t size) { return pkcs11_getattr_var(token, object, type, value, &size); } int pkcs11_getattr_s(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object, unsigned int type, void *value, size_t size) { memset(value, 0, size); return pkcs11_getattr_var(token, object, type, value, &size); } int pkcs11_getattr_bn(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object, unsigned int type, BIGNUM ** bn) { CK_BYTE *binary; size_t size; int ret; size = 0; if (pkcs11_getattr_var(token, object, type, NULL, &size) || size == 0) return -1; binary = OPENSSL_malloc(size); if (binary == NULL) return -1; memset(binary, 0, size); if (pkcs11_getattr_var(token, object, type, binary, &size)) { ret = -1; goto cleanup; } /* * @ALON: invalid object, * not sure it will survive the ulValueLen->size_t and keep sign at all platforms */ if (size == (size_t)-1) { PKCS11err(PKCS11_F_PKCS11_GETATTR, pkcs11_map_err(CKR_ATTRIBUTE_TYPE_INVALID)); ret = -1; goto cleanup; } *bn = BN_bin2bn(binary, (int) size, *bn); ret = *bn ? 0 : -1; cleanup: OPENSSL_free(binary); return ret; } /* * Add attributes to template */ void pkcs11_addattr(CK_ATTRIBUTE_PTR ap, int type, const void *data, size_t size) { ap->type = type; ap->pValue = OPENSSL_malloc(size); if (ap->pValue == NULL) return; memcpy(ap->pValue, data, size); ap->ulValueLen = size; } /* In PKCS11, virtually every integer is a CK_ULONG */ void pkcs11_addattr_int(CK_ATTRIBUTE_PTR ap, int type, unsigned long value) { CK_ULONG ulValue = value; pkcs11_addattr(ap, type, &ulValue, sizeof(ulValue)); } void pkcs11_addattr_bool(CK_ATTRIBUTE_PTR ap, int type, int value) { pkcs11_addattr(ap, type, &value, sizeof(CK_BBOOL)); } void pkcs11_addattr_s(CK_ATTRIBUTE_PTR ap, int type, const char *s) { pkcs11_addattr(ap, type, s, s ? strlen(s) : 0); /* RFC2279 string an unpadded string of CK_UTF8CHARs with no null-termination */ } void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR ap, int type, const BIGNUM * bn) { unsigned char temp[1024]; unsigned int n; assert((size_t)BN_num_bytes(bn) <= sizeof(temp)); n = BN_bn2bin(bn, temp); pkcs11_addattr(ap, type, temp, n); } void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR ap, int type, pkcs11_i2d_fn enc, void *obj) { unsigned char *p; ap->type = type; ap->ulValueLen = enc(obj, NULL); ap->pValue = OPENSSL_malloc(ap->ulValueLen); if (ap->pValue == NULL) return; p = ap->pValue; enc(obj, &p); } void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR ap, unsigned int n) { while (n--) { if (ap[n].pValue) OPENSSL_free(ap[n].pValue); } } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/p11_cert.c000066400000000000000000000165061265040137300162530ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * p11_cert.c - Handle certificates residing on a PKCS11 token * * Copyright (C) 2002, Olaf Kirch */ #include "libp11-int.h" #include static int pkcs11_find_certs(PKCS11_TOKEN *); static int pkcs11_next_cert(PKCS11_CTX *, PKCS11_TOKEN *, CK_SESSION_HANDLE); static int pkcs11_init_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o, PKCS11_CERT **); /* * Enumerate all certs on the card */ int PKCS11_enumerate_certs(PKCS11_TOKEN * token, PKCS11_CERT ** certp, unsigned int *countp) { PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token); PKCS11_CTX *ctx = TOKEN2CTX(token); PKCS11_CTX_private *cpriv = PRIVCTX(ctx); int rv; if (tpriv->ncerts < 0) { pkcs11_w_lock(cpriv->lockid); rv = pkcs11_find_certs(token); pkcs11_w_unlock(cpriv->lockid); if (rv < 0) { pkcs11_destroy_certs(token); return -1; } } if (certp) *certp = tpriv->certs; if (countp) *countp = tpriv->ncerts; return 0; } /* * Find certificate matching a key */ PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY * key) { PKCS11_KEY_private *kpriv; PKCS11_CERT_private *cpriv; PKCS11_CERT *cert; unsigned int n, count; kpriv = PRIVKEY(key); if (PKCS11_enumerate_certs(KEY2TOKEN(key), &cert, &count)) return NULL; for (n = 0; n < count; n++, cert++) { cpriv = PRIVCERT(cert); if (cpriv->id_len == kpriv->id_len && !memcmp(cpriv->id, kpriv->id, kpriv->id_len)) return cert; } return NULL; } /* * Find all certs of a given type (public or private) */ static int pkcs11_find_certs(PKCS11_TOKEN * token) { PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token); PKCS11_SLOT *slot = TOKEN2SLOT(token); PKCS11_CTX *ctx = TOKEN2CTX(token); CK_SESSION_HANDLE session; CK_OBJECT_CLASS cert_search_class; CK_ATTRIBUTE cert_search_attrs[] = { {CKA_CLASS, &cert_search_class, sizeof(cert_search_class)}, }; int rv, res = -1; /* Make sure we have a session */ if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 0)) return -1; session = PRIVSLOT(slot)->session; /* Tell the PKCS11 lib to enumerate all matching objects */ cert_search_class = CKO_CERTIFICATE; rv = CRYPTOKI_call(ctx, C_FindObjectsInit(session, cert_search_attrs, 1)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_CERTS, rv); tpriv->ncerts = 0; do { res = pkcs11_next_cert(ctx, token, session); } while (res == 0); CRYPTOKI_call(ctx, C_FindObjectsFinal(session)); return (res < 0) ? -1 : 0; } static int pkcs11_next_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token, CK_SESSION_HANDLE session) { CK_OBJECT_HANDLE obj; CK_ULONG count; int rv; /* Get the next matching object */ rv = CRYPTOKI_call(ctx, C_FindObjects(session, &obj, 1, &count)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_CERTS, rv); if (count == 0) return 1; if (pkcs11_init_cert(ctx, token, session, obj, NULL)) return -1; return 0; } static int pkcs11_init_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret) { PKCS11_TOKEN_private *tpriv; PKCS11_CERT_private *cpriv; PKCS11_CERT *cert, *tmp; char label[256]; unsigned char *data; unsigned char id[256]; CK_CERTIFICATE_TYPE cert_type; size_t size; (void)ctx; (void)session; size = sizeof(cert_type); if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, &cert_type, &size)) return -1; /* Ignore any certs we don't understand */ if (cert_type != CKC_X_509) return 0; tpriv = PRIVTOKEN(token); tmp = OPENSSL_realloc(tpriv->certs, (tpriv->ncerts + 1) * sizeof(PKCS11_CERT)); if (tmp == NULL) { OPENSSL_free(tpriv->certs); tpriv->certs = NULL; return -1; } tpriv->certs = tmp; cert = tpriv->certs + tpriv->ncerts++; memset(cert, 0, sizeof(*cert)); cpriv = OPENSSL_malloc(sizeof(PKCS11_CERT_private)); if (cpriv == NULL) return -1; memset(cpriv, 0, sizeof(PKCS11_CERT_private)); cert->_private = cpriv; cpriv->object = obj; cpriv->parent = token; if (!pkcs11_getattr_s(token, obj, CKA_LABEL, label, sizeof(label))) cert->label = BUF_strdup(label); size = 0; if (!pkcs11_getattr_var(token, obj, CKA_VALUE, NULL, &size) && size > 0) { data = OPENSSL_malloc(size); if (data) { if (!pkcs11_getattr_var(token, obj, CKA_VALUE, data, &size)) { const unsigned char *p = data; cert->x509 = d2i_X509(NULL, &p, (long) size); } OPENSSL_free(data); } } cert->id_len = sizeof(id); if (!pkcs11_getattr_var(token, obj, CKA_ID, id, &cert->id_len)) { cert->id = OPENSSL_malloc(cert->id_len); if (cert->id == NULL) return -1; memcpy(cert->id, id, cert->id_len); } /* Initialize internal information */ cpriv->id_len = sizeof(cpriv->id); if (pkcs11_getattr_var(token, obj, CKA_ID, cpriv->id, &cpriv->id_len)) cpriv->id_len = 0; if (ret) *ret = cert; return 0; } /* * Destroy all certs */ void pkcs11_destroy_certs(PKCS11_TOKEN * token) { PKCS11_TOKEN_private *priv = PRIVTOKEN(token); while (priv->ncerts > 0) { PKCS11_CERT *cert = &priv->certs[--(priv->ncerts)]; if (cert->x509) X509_free(cert->x509); OPENSSL_free(cert->label); if (cert->id) OPENSSL_free(cert->id); if (cert->_private != NULL) OPENSSL_free(cert->_private); } if (priv->certs) OPENSSL_free(priv->certs); priv->certs = NULL; priv->ncerts = -1; } /* * Store certificate */ int PKCS11_store_certificate(PKCS11_TOKEN * token, X509 * x509, char *label, unsigned char *id, size_t id_len, PKCS11_CERT ** ret_cert) { PKCS11_SLOT *slot = TOKEN2SLOT(token); PKCS11_CTX *ctx = TOKEN2CTX(token); CK_SESSION_HANDLE session; CK_OBJECT_HANDLE object; CK_ATTRIBUTE attrs[32]; unsigned int n = 0; int rv; CHECK_SLOT_FORK(slot); /* First, make sure we have a session */ if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1)) return -1; session = PRIVSLOT(slot)->session; /* Now build the template */ pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_CERTIFICATE); pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE); pkcs11_addattr_int(attrs + n++, CKA_CERTIFICATE_TYPE, CKC_X_509); pkcs11_addattr_obj(attrs + n++, CKA_VALUE, (pkcs11_i2d_fn) i2d_X509, x509); if (label) pkcs11_addattr_s(attrs + n++, CKA_LABEL, label); if (id && id_len) pkcs11_addattr(attrs + n++, CKA_ID, id, id_len); /* Now call the pkcs11 module to create the object */ rv = CRYPTOKI_call(ctx, C_CreateObject(session, attrs, n, &object)); /* Zap all memory allocated when building the template */ pkcs11_zap_attrs(attrs, n); CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_CERTIFICATE, rv); /* Gobble the key object */ return pkcs11_init_cert(ctx, token, session, object, ret_cert); } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/p11_ec.c000066400000000000000000000217511265040137300157030ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * Copyright (C) 2011, 2013 Douglas E. Engert * Copyright (C) 2014 Douglas E. Engert * Copyright (C) 2016 Michał Trojnara * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * This file implements the handling of EC keys stored on a * PKCS11 token */ #include "libp11-int.h" #include #include #include #define LIBP11_BUILD_WITHOUT_ECDSA #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) #undef LIBP11_BUILD_WITHOUT_ECDSA #include #include #include /* To build this mode, * OpenSSL has ECDSA_METHOD defined in internal header file ecs_locl.h * Until this is resolved use something like: * CPPFLAGS="-DBUILD_WITH_ECS_LOCL_H -I/path.to.openssl-1.0.1e/src/crypto/ecdsa" * See OpenSSL bug report #2459 02/23/2011 * Once OpenSSL addresses the issues this code will be changed. * * OpenSSL mods were submitted 09/2013 that will set ECDSA_F_ECDSA_METHOD_NEW * and define the ECDSA_METHOD_new and friends functions * These mods are in OpenSSL-1.0.2-beta * We will try both methods. */ #if defined(ECDSA_F_ECDSA_METHOD_NEW) && defined(BUILD_WITH_ECS_LOCL_H) #warning "Both BUILD_WITH_ECS_LOCL_H and ECDSA_F_ECDSA_METHOD_NEW defined" #warning "Consider not using BUILD_WITH_ECS_LOCL_H" #endif #if defined(BUILD_WITH_ECS_LOCL_H) #warning "Consider not using BUILD_WITH_ECS_LOCL_H" #warning "newer version of OpenSSL >-1.0.2 does not need BUILD_WITH_ECS_LOCL_H" #include "ecs_locl.h" #if !defined(HEADER_ECS_LOCL_H) #warning "Unable to find OpenSSL src/crypto/ecs_locl.h" #warning "add to CPPFLAGS: -I/path/to/source/openssl-n.n.n/src/crypto/ecdsa" #warning "or copy ecs_locl.h or create symlink to it" #if defined(ECDSA_F_ECDSA_METHOD_NEW) #warning "Will build instead using ECDSA_F_ECDSA_METHOD_NEW" #else #error "Unable to build with ECDSA support" #endif #else #define LIBP11_BUILD_WITH_ECS_LOCL_H #endif #else #if !defined(ECDSA_F_ECDSA_METHOD_NEW) #define LIBP11_BUILD_WITHOUT_ECDSA #endif #endif #endif /* OpenSSL EC tests and version */ #if !defined(LIBP11_BUILD_WITHOUT_ECDSA) static ECDSA_METHOD *ops = NULL; static int ecdsa_ex_index = 0; /* * Get EC key material and stash pointer in ex_data * Note we get called twice, once for private key, and once for public * We need to get the EC_PARAMS and EC_POINT into both, * as lib11 dates from RSA only where all the pub key components * were also part of the private key. With EC the point * is not in the private key, and the params may or may not be. * */ static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_KEY * key) { EVP_PKEY *pk; EC_KEY * ec = NULL; CK_RV ckrv; size_t ec_paramslen = 0; CK_BYTE * ec_params = NULL; size_t ec_pointlen = 0; CK_BYTE * ec_point = NULL; PKCS11_KEY * pubkey; ASN1_OCTET_STRING *os=NULL; pk = EVP_PKEY_new(); if (pk == NULL) return NULL; ec = EC_KEY_new(); if (ec == NULL) { EVP_PKEY_free(pk); return NULL; } EVP_PKEY_set1_EC_KEY(pk, ec); /* Also increments the ec ref count */ /* For Openssl req we need at least the * EC_KEY_get0_group(ec_key)) to return the group. * Even if it fails will continue as a sign only does not need * need this if the pkcs11 or card can figure this out. */ if (key_getattr_var(key, CKA_EC_PARAMS, NULL, &ec_paramslen) == CKR_OK && ec_paramslen > 0) { ec_params = OPENSSL_malloc(ec_paramslen); if (ec_params) { ckrv = key_getattr_var(key, CKA_EC_PARAMS, ec_params, &ec_paramslen); if (ckrv == CKR_OK) { const unsigned char * a = ec_params; /* convert to OpenSSL parmas */ d2i_ECParameters(&ec, &a, (long) ec_paramslen); } } } /* Now get the ec_point */ pubkey = key->isPrivate ? PKCS11_find_key_from_key(key) : key; if (pubkey) { ckrv = key_getattr_var(pubkey, CKA_EC_POINT, NULL, &ec_pointlen); if (ckrv == CKR_OK && ec_pointlen > 0) { ec_point = OPENSSL_malloc(ec_pointlen); if (ec_point) { ckrv = key_getattr_var(pubkey, CKA_EC_POINT, ec_point, &ec_pointlen); if (ckrv == CKR_OK) { /* PKCS#11 returns ASN1 octstring*/ const unsigned char * a; /* we have asn1 octet string, need to strip off 04 len */ a = ec_point; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long) ec_pointlen); if (os) { a = os->data; o2i_ECPublicKey(&ec, &a, os->length); } /* EC_KEY_print_fp(stderr, ec, 5); */ } } } } /* If the key is not extractable, create a key object * that will use the card's functions to sign & decrypt */ if (os) M_ASN1_OCTET_STRING_free(os); if (ec_point) OPENSSL_free(ec_point); if (ec_params) OPENSSL_free(ec_params); if (key->isPrivate) ECDSA_set_method(ec, PKCS11_get_ecdsa_method()); /* TODO: Retrieve the ECDSA private key object attributes instead, * unless the key has the "sensitive" attribute set */ ECDSA_set_ex_data(ec, ecdsa_ex_index, key); EC_KEY_free(ec); /* drops our reference to it */ return pk; } /* TODO Looks like this is never called */ static int pkcs11_ecdsa_sign_setup(EC_KEY *ec, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) { if (*kinvp != NULL) BN_clear_free(*kinvp); *kinvp = BN_new(); if (*rp != NULL) BN_clear_free(*rp); *rp = BN_new(); return 1; } static ECDSA_SIG * pkcs11_ecdsa_do_sign(const unsigned char *dgst, int dlen, const BIGNUM *inv, const BIGNUM *r, EC_KEY * ec) { unsigned char sigret[512]; /* HACK for now */ ECDSA_SIG * sig = NULL; PKCS11_KEY * key = NULL; unsigned int siglen; int nLen = 48; /* HACK */ int rv; key = (PKCS11_KEY *) ECDSA_get_ex_data(ec, ecdsa_ex_index); if (key == NULL) return NULL; siglen = sizeof(sigret); rv = PKCS11_ecdsa_sign(dgst, dlen, sigret, &siglen, key); nLen = siglen / 2; if (rv > 0) { sig = ECDSA_SIG_new(); if (sig) { BN_bin2bn(&sigret[0], nLen, sig->r); BN_bin2bn(&sigret[nLen], nLen, sig->s); } } return sig; } static void alloc_ecdsa_ex_index() { if (ecdsa_ex_index == 0) { while (ecdsa_ex_index == 0) /* Workaround for OpenSSL RT3710 */ ecdsa_ex_index = ECDSA_get_ex_new_index(0, "libp11 ecdsa", NULL, NULL, NULL); if (ecdsa_ex_index < 0) ecdsa_ex_index = 0; /* Fallback to app_data */ } } static void free_ecdsa_ex_index() { /* CRYPTO_free_ex_index requires OpenSSL version >= 1.1.0-pre1 */ #if OPENSSL_VERSION_NUMBER >= 0x10100001L if (ecdsa_ex_index > 0) { CRYPTO_free_ex_index(CRYPTO_EX_INDEX_ECDSA, ecdsa_ex_index); ecdsa_ex_index = 0; } #endif } /* * Overload the default OpenSSL methods for ECDSA * If OpenSSL supports ECDSA_METHOD_new we will use it. * Otherwise we expect the ecs_locl.h to be present. */ #if !defined(LIBP11_BUILD_WITH_ECS_LOCL_H) /* New way to allocate an ECDSA_METOD object */ ECDSA_METHOD *PKCS11_get_ecdsa_method(void) { alloc_ecdsa_ex_index(); if (ops == NULL) { ops = ECDSA_METHOD_new((ECDSA_METHOD *)ECDSA_OpenSSL()); ECDSA_METHOD_set_sign(ops, pkcs11_ecdsa_do_sign); ECDSA_METHOD_set_sign_setup(ops, pkcs11_ecdsa_sign_setup); } return ops; } void PKCS11_ecdsa_method_free(void) { if (ops) { ECDSA_METHOD_free(ops); ops = NULL; } free_ecdsa_ex_index(); } #else /* LIBP11_BUILD_WITH_ECS_LOCL_H */ /* Old way using ecs_locl.h */ ECDSA_METHOD *PKCS11_get_ecdsa_method(void) { static struct ecdsa_method sops; alloc_ecdsa_ex_index(); if (!sops.ecdsa_do_sign) { /* question if compiler is copying each member of struct or not */ sops = *ECDSA_get_default_method(); sops.ecdsa_do_sign = pkcs11_ecdsa_do_sign; sops.ecdsa_sign_setup = pkcs11_ecdsa_sign_setup; } return &sops; } void PKCS11_ecdsa_method_free(void) { /* It is static in the old method */ free_ecdsa_ex_index(); } #endif /* LIBP11_BUILD_WITH_ECS_LOCL_H */ PKCS11_KEY_ops pkcs11_ec_ops_s = { EVP_PKEY_EC, pkcs11_get_evp_key_ec }; PKCS11_KEY_ops *pkcs11_ec_ops = {&pkcs11_ec_ops_s}; #else /* LIBP11_BUILD_WITHOUT_ECDSA */ PKCS11_KEY_ops *pkcs11_ec_ops = {NULL}; /* if not built with EC or OpenSSL does not support ECDSA * add these routines so engine_pkcs11 can be built now and not * require further changes */ #warning "ECDSA support not built with libp11" ECDSA_METHOD *PKCS11_get_ecdsa_method(void) { return NULL; } void PKCS11_ecdsa_method_free(void) { /* no op, as it is static in the old code */ } #endif /* LIBP11_BUILD_WITHOUT_ECDSA */ /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/p11_err.c000066400000000000000000000163571265040137300161120ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "libp11-int.h" /* BEGIN ERROR CODES */ #ifndef NO_ERR static ERR_STRING_DATA PKCS11_str_library[] = { {ERR_PACK(ERR_LIB_PKCS11, 0, 0), "PKCS11 library"}, {0, NULL} }; static ERR_STRING_DATA PKCS11_str_functs[] = { {ERR_PACK(0, PKCS11_F_PKCS11_CTX_LOAD, 0), "PKCS11_CTX_load"}, {ERR_PACK(0, PKCS11_F_PKCS11_ENUM_SLOTS, 0), "PKCS11_enum_slots"}, {ERR_PACK(0, PKCS11_F_PKCS11_CHECK_TOKEN, 0), "PKCS11_check_token"}, {ERR_PACK(0, PKCS11_F_PKCS11_OPEN_SESSION, 0), "PKCS11_open_session"}, {ERR_PACK(0, PKCS11_F_PKCS11_LOGIN, 0), "PKCS11_login"}, {ERR_PACK(0, PKCS11_F_PKCS11_ENUM_KEYS, 0), "PKCS11_enum_keys"}, {ERR_PACK(0, PKCS11_F_PKCS11_GET_KEY, 0), "PKCS11_get_key"}, {ERR_PACK(0, PKCS11_F_PKCS11_RSA_DECRYPT, 0), "PKCS11_rsa_decrypt"}, {ERR_PACK(0, PKCS11_F_PKCS11_RSA_ENCRYPT, 0), "PKCS11_rsa_encrypt"}, {ERR_PACK(0, PKCS11_F_PKCS11_RSA_SIGN, 0), "PKCS11_rsa_sign"}, {ERR_PACK(0, PKCS11_F_PKCS11_RSA_VERIFY, 0), "PKCS11_rsa_verify"}, {ERR_PACK(0, PKCS11_F_PKCS11_ENUM_CERTS, 0), "PKCS11_enum_certs"}, {ERR_PACK(0, PKCS11_F_PKCS11_INIT_TOKEN, 0), "PKCS11_init_token"}, {ERR_PACK(0, PKCS11_F_PKCS11_INIT_PIN, 0), "PKCS11_init_pin"}, {ERR_PACK(0, PKCS11_F_PKCS11_GETATTR, 0), "PKCS11_get_attribute"}, {ERR_PACK(0, PKCS11_F_PKCS11_LOGOUT, 0), "PKCS11_logout"}, {ERR_PACK(0, PKCS11_F_PKCS11_STORE_PRIVATE_KEY, 0), "PKCS11_store_private_key"}, {ERR_PACK(0, PKCS11_F_PKCS11_GENERATE_KEY, 0), "PKCS11_generate_key"}, {ERR_PACK(0, PKCS11_F_PKCS11_STORE_PUBLIC_KEY, 0), "PKCS11_store_public_key"}, {ERR_PACK(0, PKCS11_F_PKCS11_STORE_CERTIFICATE, 0), "PKCS11_store_certificate"}, {ERR_PACK(0, PKCS11_F_PKCS11_CHANGE_PIN, 0), "PKCS11_change_pin"}, {0, NULL} }; static ERR_STRING_DATA PKCS11_str_reasons[] = { {PKCS11_LOAD_MODULE_ERROR, "Unable to load PKCS#11 module"}, {PKCS11_MODULE_LOADED_ERROR, "Already loaded module for PKCS11 context"}, {PKCS11_SYMBOL_NOT_FOUND_ERROR, "Symbol not found in PKCS#11 module"}, {PKCS11_NOT_SUPPORTED, "Not supported"}, {PKCS11_NO_SESSION, "No session open"}, {CKR_CANCEL, "Cancel"}, {CKR_HOST_MEMORY, "Host memory error"}, {CKR_SLOT_ID_INVALID, "Invalid slot ID"}, {CKR_GENERAL_ERROR, "General Error"}, {CKR_FUNCTION_FAILED, "Function failed"}, {CKR_ARGUMENTS_BAD, "Invalid arguments"}, {CKR_NO_EVENT, "No event"}, {CKR_NEED_TO_CREATE_THREADS, "Need to create threads"}, {CKR_CANT_LOCK, "Cannott lock"}, {CKR_ATTRIBUTE_READ_ONLY, "Attribute read only"}, {CKR_ATTRIBUTE_SENSITIVE, "Attribute sensitive"}, {CKR_ATTRIBUTE_TYPE_INVALID, "Attribute type invalid"}, {CKR_ATTRIBUTE_VALUE_INVALID, "Attribute value invalid"}, {CKR_DATA_INVALID, "Data invalid"}, {CKR_DATA_LEN_RANGE, "Data len range"}, {CKR_DEVICE_ERROR, "Device error"}, {CKR_DEVICE_MEMORY, "Device memory"}, {CKR_DEVICE_REMOVED, "Device removed"}, {CKR_ENCRYPTED_DATA_INVALID, "Encrypted data invalid"}, {CKR_ENCRYPTED_DATA_LEN_RANGE, "Encrypted data len range"}, {CKR_FUNCTION_CANCELED, "Function canceled"}, {CKR_FUNCTION_NOT_PARALLEL, "Function not parallel"}, {CKR_FUNCTION_NOT_SUPPORTED, "Function not supported"}, {CKR_KEY_HANDLE_INVALID, "Key handle invalid"}, {CKR_KEY_SIZE_RANGE, "Key size range"}, {CKR_KEY_TYPE_INCONSISTENT, "Key type inconsistent"}, {CKR_KEY_NOT_NEEDED, "Key not needed"}, {CKR_KEY_CHANGED, "Key changed"}, {CKR_KEY_NEEDED, "Key needed"}, {CKR_KEY_INDIGESTIBLE, "Key indigestible"}, {CKR_KEY_FUNCTION_NOT_PERMITTED, "Key function not permitted"}, {CKR_KEY_NOT_WRAPPABLE, "Key not wrappable"}, {CKR_KEY_UNEXTRACTABLE, "Key unextractable"}, {CKR_MECHANISM_INVALID, "Mechanism invalid"}, {CKR_MECHANISM_PARAM_INVALID, "Mechanism param invalid"}, {CKR_OBJECT_HANDLE_INVALID, "Object handle invalid"}, {CKR_OPERATION_ACTIVE, "Operation active"}, {CKR_OPERATION_NOT_INITIALIZED, "Operation not initialized"}, {CKR_PIN_INCORRECT, "PIN incorrect"}, {CKR_PIN_INVALID, "PIN invalid"}, {CKR_PIN_LEN_RANGE, "Invalid PIN length"}, {CKR_PIN_EXPIRED, "PIN expired"}, {CKR_PIN_LOCKED, "PIN locked"}, {CKR_SESSION_CLOSED, "Session closed"}, {CKR_SESSION_COUNT, "Session count"}, {CKR_SESSION_HANDLE_INVALID, "Session handle invalid"}, {CKR_SESSION_PARALLEL_NOT_SUPPORTED, "Session parallel not supported"}, {CKR_SESSION_READ_ONLY, "Session read only"}, {CKR_SESSION_EXISTS, "Session exists"}, {CKR_SESSION_READ_ONLY_EXISTS, "Read-only session exists"}, {CKR_SESSION_READ_WRITE_SO_EXISTS, "Read/write SO session exists"}, {CKR_SIGNATURE_INVALID, "Signature invalid"}, {CKR_SIGNATURE_LEN_RANGE, "Signature len range"}, {CKR_TEMPLATE_INCOMPLETE, "Incomplete template"}, {CKR_TEMPLATE_INCONSISTENT, "Inconsistent template"}, {CKR_TOKEN_NOT_PRESENT, "No PKCS#11 token present"}, {CKR_TOKEN_NOT_RECOGNIZED, "PKCS#11 token not recognized"}, {CKR_TOKEN_WRITE_PROTECTED, "Token write protected"}, {CKR_UNWRAPPING_KEY_HANDLE_INVALID, "Unwrapping key handle invalid"}, {CKR_UNWRAPPING_KEY_SIZE_RANGE, "Unwrapping key size range"}, {CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "Unwrapping key type inconsistent"}, {CKR_USER_ALREADY_LOGGED_IN, "User already logged in"}, {CKR_USER_NOT_LOGGED_IN, "User not logged in"}, {CKR_USER_PIN_NOT_INITIALIZED, "User pin not initialized"}, {CKR_USER_TYPE_INVALID, "User type invalid"}, {CKR_USER_ANOTHER_ALREADY_LOGGED_IN, "User another is already logged in"}, {CKR_USER_TOO_MANY_TYPES, "User too many types"}, {CKR_WRAPPED_KEY_INVALID, "Wrapped key invalid"}, {CKR_WRAPPED_KEY_LEN_RANGE, "Wrapped key len range"}, {CKR_WRAPPING_KEY_HANDLE_INVALID, "Wrapping key handle invalid"}, {CKR_WRAPPING_KEY_SIZE_RANGE, "Wrapping key size range"}, {CKR_WRAPPING_KEY_TYPE_INCONSISTENT, "Wrapping key type inconsistent"}, {CKR_RANDOM_SEED_NOT_SUPPORTED, "Random seed not supported"}, {CKR_RANDOM_NO_RNG, "Random no rng"}, {CKR_DOMAIN_PARAMS_INVALID, "Domain params invalid"}, {CKR_BUFFER_TOO_SMALL, "Buffer too small"}, {CKR_SAVED_STATE_INVALID, "Saved state invalid"}, {CKR_INFORMATION_SENSITIVE, "Information sensitive"}, {CKR_STATE_UNSAVEABLE, "State unsaveable"}, {CKR_CRYPTOKI_NOT_INITIALIZED, "Cryptoki not initialized"}, {CKR_CRYPTOKI_ALREADY_INITIALIZED, "Cryptoki already initialized"}, {CKR_MUTEX_BAD, "Mutex bad"}, {CKR_MUTEX_NOT_LOCKED, "Mutex not locked"}, {CKR_VENDOR_DEFINED, "Vendor defined"}, {0, NULL} }; #endif void ERR_load_PKCS11_strings(void) { static int init = 1; if (init) { init = 0; #ifndef NO_ERR ERR_load_strings(0, PKCS11_str_library); ERR_load_strings(ERR_LIB_PKCS11, PKCS11_str_functs); ERR_load_strings(ERR_LIB_PKCS11, PKCS11_str_reasons); #endif } } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/p11_key.c000066400000000000000000000325321265040137300161030ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * Copyright (C) 2016 Michał Trojnara * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "libp11-int.h" #include #ifdef _WIN32 #define strncasecmp strnicmp #endif static int pkcs11_enumerate_keys(PKCS11_TOKEN *, unsigned int, PKCS11_KEY **, unsigned int *); static int pkcs11_find_keys(PKCS11_TOKEN *, unsigned int); static int pkcs11_next_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token, CK_SESSION_HANDLE session, CK_OBJECT_CLASS type); static int pkcs11_init_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o, CK_OBJECT_CLASS type, PKCS11_KEY **); static int pkcs11_store_key(PKCS11_TOKEN *, EVP_PKEY *, unsigned int, char *, unsigned char *, size_t, PKCS11_KEY **); /* * Enumerate private keys on the card */ int PKCS11_enumerate_keys(PKCS11_TOKEN * token, PKCS11_KEY ** keyp, unsigned int *countp) { return pkcs11_enumerate_keys(token, CKO_PRIVATE_KEY, keyp, countp); } /* * Enumerate public keys on the card */ int PKCS11_enumerate_public_keys(PKCS11_TOKEN * token, PKCS11_KEY ** keyp, unsigned int *countp) { return pkcs11_enumerate_keys(token, CKO_PUBLIC_KEY, keyp, countp); } /* * Find key matching a certificate */ PKCS11_KEY *PKCS11_find_key(PKCS11_CERT *cert) { PKCS11_CERT_private *cpriv; PKCS11_KEY_private *kpriv; PKCS11_KEY *keys; unsigned int n, count; cpriv = PRIVCERT(cert); if (PKCS11_enumerate_keys(CERT2TOKEN(cert), &keys, &count)) return NULL; for (n = 0; n < count; n++) { kpriv = PRIVKEY(&keys[n]); if (cpriv->id_len == kpriv->id_len && !memcmp(cpriv->id, kpriv->id, cpriv->id_len)) return &keys[n]; } return NULL; } /* * Find key matching a key of the other type pub vs priv */ PKCS11_KEY *PKCS11_find_key_from_key(PKCS11_KEY * keyin) { PKCS11_KEY_private *kinpriv = PRIVKEY(keyin); PKCS11_KEY *keys; unsigned int n, count; pkcs11_enumerate_keys(KEY2TOKEN(keyin), keyin->isPrivate ? CKO_PUBLIC_KEY : CKO_PRIVATE_KEY, /* other type */ &keys, &count); for (n = 0; n < count; n++) { PKCS11_KEY_private *kpriv = PRIVKEY(&keys[n]); if (kinpriv->id_len == kpriv->id_len && !memcmp(kinpriv->id, kpriv->id, kinpriv->id_len)) return &keys[n]; } return NULL; } /* * Reopens the object associated with the key */ int pkcs11_reload_key(PKCS11_KEY * key) { PKCS11_KEY_private *kpriv = PRIVKEY(key); PKCS11_SLOT *slot = KEY2SLOT(key); PKCS11_SLOT_private *spriv = PRIVSLOT(slot); PKCS11_CTX *ctx = SLOT2CTX(slot); CK_OBJECT_CLASS key_search_class = key->isPrivate ? CKO_PRIVATE_KEY : CKO_PUBLIC_KEY; CK_ATTRIBUTE key_search_attrs[2] = { {CKA_CLASS, &key_search_class, sizeof(key_search_class)}, {CKA_ID, kpriv->id, kpriv->id_len}, }; CK_ULONG count; int rv; /* this is already covered with a per-ctx lock */ rv = CRYPTOKI_call(ctx, C_FindObjectsInit(spriv->session, key_search_attrs, 2)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_KEYS, rv); rv = CRYPTOKI_call(ctx, C_FindObjects(spriv->session, &kpriv->object, 1, &count)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_KEYS, rv); CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session)); return 0; } /* * Generate and store a private key on the token * FIXME: We should check first whether the token supports * on-board key generation, and if it does, use its own algorithm */ int PKCS11_generate_key(PKCS11_TOKEN * token, int algorithm, unsigned int bits, char *label, unsigned char* id, size_t id_len) { PKCS11_KEY *key_obj; EVP_PKEY *pk; RSA *rsa; BIO *err; int rc; if (algorithm != EVP_PKEY_RSA) { PKCS11err(PKCS11_F_PKCS11_GENERATE_KEY, PKCS11_NOT_SUPPORTED); return -1; } err = BIO_new_fp(stderr, BIO_NOCLOSE); rsa = RSA_generate_key(bits, RSA_F4, NULL, err); BIO_free(err); if (rsa == NULL) { PKCS11err(PKCS11_F_PKCS11_GENERATE_KEY, PKCS11_KEYGEN_FAILED); return -1; } pk = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pk, rsa); rc = pkcs11_store_key(token, pk, CKO_PRIVATE_KEY, label, id, id_len, &key_obj); if (rc == 0) { PKCS11_KEY_private *kpriv; kpriv = PRIVKEY(key_obj); rc = pkcs11_store_key(token, pk, CKO_PUBLIC_KEY, label, kpriv->id, kpriv->id_len, NULL); } EVP_PKEY_free(pk); return rc; } /* * Store a private key on the token */ int PKCS11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len) { if (pkcs11_store_key(token, pk, CKO_PRIVATE_KEY, label, id, id_len, NULL)) return -1; return 0; } int PKCS11_store_public_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len) { if (pkcs11_store_key(token, pk, CKO_PUBLIC_KEY, label, id, id_len, NULL)) return -1; return 0; } /* * Store private key */ static int pkcs11_store_key(PKCS11_TOKEN * token, EVP_PKEY * pk, unsigned int type, char *label, unsigned char *id, size_t id_len, PKCS11_KEY ** ret_key) { PKCS11_SLOT *slot = TOKEN2SLOT(token); PKCS11_CTX *ctx = TOKEN2CTX(token); CK_SESSION_HANDLE session; CK_OBJECT_HANDLE object; CK_ATTRIBUTE attrs[32]; unsigned int n = 0; int rv; CHECK_SLOT_FORK(slot); /* First, make sure we have a session */ if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1)) return -1; session = PRIVSLOT(slot)->session; /* Now build the key attrs */ pkcs11_addattr_int(attrs + n++, CKA_CLASS, type); if (label) pkcs11_addattr_s(attrs + n++, CKA_LABEL, label); if (id && id_len) pkcs11_addattr(attrs + n++, CKA_ID, id, id_len); pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE); if (type == CKO_PRIVATE_KEY) { pkcs11_addattr_bool(attrs + n++, CKA_PRIVATE, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_SENSITIVE, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_DECRYPT, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_SIGN, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_UNWRAP, TRUE); } else { /* CKO_PUBLIC_KEY */ pkcs11_addattr_bool(attrs + n++, CKA_ENCRYPT, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_VERIFY, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_WRAP, TRUE); } if (pk->type == EVP_PKEY_RSA) { RSA *rsa = EVP_PKEY_get1_RSA(pk); pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA); pkcs11_addattr_bn(attrs + n++, CKA_MODULUS, rsa->n); pkcs11_addattr_bn(attrs + n++, CKA_PUBLIC_EXPONENT, rsa->e); if (type == CKO_PRIVATE_KEY) { pkcs11_addattr_bn(attrs + n++, CKA_PRIVATE_EXPONENT, rsa->d); pkcs11_addattr_bn(attrs + n++, CKA_PRIME_1, rsa->p); pkcs11_addattr_bn(attrs + n++, CKA_PRIME_2, rsa->q); } } else { pkcs11_zap_attrs(attrs, n); PKCS11err(type == CKO_PRIVATE_KEY ? PKCS11_F_PKCS11_STORE_PRIVATE_KEY : PKCS11_F_PKCS11_STORE_PUBLIC_KEY, PKCS11_NOT_SUPPORTED); return -1; } /* Now call the pkcs11 module to create the object */ rv = CRYPTOKI_call(ctx, C_CreateObject(session, attrs, n, &object)); /* Zap all memory allocated when building the template */ pkcs11_zap_attrs(attrs, n); CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_PRIVATE_KEY, rv); /* Gobble the key object */ return pkcs11_init_key(ctx, token, session, object, type, ret_key); } /* * Get the key type */ int PKCS11_get_key_type(PKCS11_KEY * key) { PKCS11_KEY_private *kpriv = PRIVKEY(key); return kpriv->ops->type; } /* * Create an EVP_PKEY OpenSSL object for a given key * Returns either private or public key object depending on the isPrivate * value for compatibility with a bug in engine_pkcs11 <= 0.2.0 * TODO: Fix this when the affected engine_pkcs11 is phased out */ EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY * key) { PKCS11_KEY_private *kpriv; if (key == NULL) return NULL; if (key->evp_key == NULL) { kpriv = PRIVKEY(key); key->evp_key = kpriv->ops->get_evp_key(key); } return key->evp_key; } /* * Create an EVP_PKEY OpenSSL object for a given key * Always returns the public key object */ EVP_PKEY *PKCS11_get_public_key(PKCS11_KEY * key) { PKCS11_KEY_private *kpriv; if (key == NULL) return NULL; if (key->isPrivate) { key = PKCS11_find_key_from_key(key); if (key == NULL) return NULL; } if (key->evp_key == NULL) { kpriv = PRIVKEY(key); key->evp_key = kpriv->ops->get_evp_key(key); } return key->evp_key; } /* * Return keys of a given type (public or private) * Use the cached values if available */ static int pkcs11_enumerate_keys(PKCS11_TOKEN * token, unsigned int type, PKCS11_KEY ** keyp, unsigned int * countp) { PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token); PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub; PKCS11_CTX *ctx = TOKEN2CTX(token); PKCS11_CTX_private *cpriv = PRIVCTX(ctx); int rv; if (keys->num < 0) { /* No cache was built for the specified type */ pkcs11_w_lock(cpriv->lockid); rv = pkcs11_find_keys(token, type); pkcs11_w_unlock(cpriv->lockid); if (rv < 0) { pkcs11_destroy_keys(token, type); return -1; } } if (keyp) *keyp = keys->keys; if (countp) *countp = keys->num; return 0; } /* * Find all keys of a given type (public or private) */ static int pkcs11_find_keys(PKCS11_TOKEN * token, unsigned int type) { PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token); PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub; PKCS11_SLOT *slot = TOKEN2SLOT(token); PKCS11_SLOT_private *spriv = PRIVSLOT(slot); PKCS11_CTX *ctx = TOKEN2CTX(token); CK_OBJECT_CLASS key_search_class; CK_ATTRIBUTE key_search_attrs[1] = { {CKA_CLASS, &key_search_class, sizeof(key_search_class)}, }; int rv, res = -1; /* Make sure we have a session */ if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 0)) return -1; /* Tell the PKCS11 lib to enumerate all matching objects */ key_search_class = type; rv = CRYPTOKI_call(ctx, C_FindObjectsInit(spriv->session, key_search_attrs, 1)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_KEYS, rv); keys->num = 0; do { res = pkcs11_next_key(ctx, token, spriv->session, type); } while (res == 0); CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session)); return (res < 0) ? -1 : 0; } static int pkcs11_next_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token, CK_SESSION_HANDLE session, CK_OBJECT_CLASS type) { CK_OBJECT_HANDLE obj; CK_ULONG count; int rv; /* Get the next matching object */ rv = CRYPTOKI_call(ctx, C_FindObjects(session, &obj, 1, &count)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_KEYS, rv); if (count == 0) return 1; if (pkcs11_init_key(ctx, token, session, obj, type, NULL)) return -1; return 0; } static int pkcs11_init_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, CK_OBJECT_CLASS type, PKCS11_KEY ** ret) { PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token); PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub; PKCS11_KEY_private *kpriv; PKCS11_KEY *key, *tmp; char label[256]; unsigned char id[256]; CK_KEY_TYPE key_type; PKCS11_KEY_ops *ops; size_t size; (void)ctx; (void)session; size = sizeof(key_type); if (pkcs11_getattr_var(token, obj, CKA_KEY_TYPE, &key_type, &size)) return -1; switch (key_type) { case CKK_RSA: ops = &pkcs11_rsa_ops; break; case CKK_EC: ops = pkcs11_ec_ops; if (ops == NULL) return 0; /* not supported */ break; default: /* Ignore any keys we don't understand */ return 0; } tmp = OPENSSL_realloc(keys->keys, (keys->num + 1) * sizeof(PKCS11_KEY)); if (tmp == NULL) { OPENSSL_free(keys->keys); keys->keys = NULL; return -1; } keys->keys = tmp; key = keys->keys + keys->num++; memset(key, 0, sizeof(PKCS11_KEY)); kpriv = OPENSSL_malloc(sizeof(PKCS11_KEY_private)); if (kpriv) memset(kpriv, 0, sizeof(PKCS11_KEY_private)); key->_private = kpriv; kpriv->object = obj; kpriv->parent = token; if (!pkcs11_getattr_s(token, obj, CKA_LABEL, label, sizeof(label))) key->label = BUF_strdup(label); key->id_len = sizeof(id); if (!pkcs11_getattr_var(token, obj, CKA_ID, id, &key->id_len)) { key->id = OPENSSL_malloc(key->id_len); memcpy(key->id, id, key->id_len); } key->isPrivate = (type == CKO_PRIVATE_KEY); /* Initialize internal information */ kpriv->id_len = sizeof(kpriv->id); if (pkcs11_getattr_var(token, obj, CKA_ID, kpriv->id, &kpriv->id_len)) kpriv->id_len = 0; kpriv->ops = ops; kpriv->forkid = _P11_get_forkid(); if (ret) *ret = key; return 0; } /* * Destroy all keys of a given type (public or private) */ void pkcs11_destroy_keys(PKCS11_TOKEN * token, unsigned int type) { PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token); PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub; while (keys->num > 0) { PKCS11_KEY *key = &keys->keys[--(keys->num)]; if (key->evp_key) EVP_PKEY_free(key->evp_key); OPENSSL_free(key->label); if (key->id) OPENSSL_free(key->id); if (key->_private != NULL) OPENSSL_free(key->_private); } if (keys->keys) OPENSSL_free(keys->keys); keys->keys = NULL; keys->num = -1; } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/p11_load.c000066400000000000000000000105731265040137300162330ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "libp11-int.h" #include static void *handle = NULL; /* * Create a new context */ PKCS11_CTX *PKCS11_CTX_new(void) { PKCS11_CTX_private *priv = NULL; PKCS11_CTX *ctx = NULL; /* Load error strings */ ERR_load_PKCS11_strings(); priv = OPENSSL_malloc(sizeof(PKCS11_CTX_private)); if (priv == NULL) goto fail; memset(priv, 0, sizeof(PKCS11_CTX_private)); ctx = OPENSSL_malloc(sizeof(PKCS11_CTX)); if (ctx == NULL) goto fail; memset(ctx, 0, sizeof(PKCS11_CTX)); ctx->_private = priv; priv->forkid = _P11_get_forkid(); priv->lockid = pkcs11_get_new_dynlockid(); return ctx; fail: OPENSSL_free(priv); OPENSSL_free(ctx); return NULL; } /* * Set private init args for module */ void PKCS11_CTX_init_args(PKCS11_CTX * ctx, const char *init_args) { PKCS11_CTX_private *priv = PRIVCTX(ctx); /* Free previously duplicated string */ if (priv->init_args) { OPENSSL_free(priv->init_args); } priv->init_args = init_args ? BUF_strdup(init_args) : NULL; } /* * Load the shared library, and initialize it. */ int PKCS11_CTX_load(PKCS11_CTX * ctx, const char *name) { PKCS11_CTX_private *priv = PRIVCTX(ctx); CK_C_INITIALIZE_ARGS _args; CK_C_INITIALIZE_ARGS *args = NULL; CK_INFO ck_info; int rv; if (priv->libinfo != NULL) { PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_MODULE_LOADED_ERROR); return -1; } handle = C_LoadModule(name, &priv->method); if (handle == NULL) { PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_LOAD_MODULE_ERROR); return -1; } /* Tell the PKCS11 to initialize itself */ if (priv->init_args != NULL) { memset(&_args, 0, sizeof(_args)); args = &_args; /* Unconditionally say using OS locking primitives is OK */ args->flags |= CKF_OS_LOCKING_OK; args->pReserved = priv->init_args; } rv = priv->method->C_Initialize(args); if (rv && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) { PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, rv); return -1; } /* Get info on the library */ rv = priv->method->C_GetInfo(&ck_info); CRYPTOKI_checkerr(PKCS11_F_PKCS11_CTX_LOAD, rv); ctx->manufacturer = PKCS11_DUP(ck_info.manufacturerID); ctx->description = PKCS11_DUP(ck_info.libraryDescription); return 0; } /* * Reinitialize (e.g., after a fork). */ int PKCS11_CTX_reload(PKCS11_CTX * ctx) { PKCS11_CTX_private *priv = PRIVCTX(ctx); CK_C_INITIALIZE_ARGS _args; CK_C_INITIALIZE_ARGS *args = NULL; int rv; /* Tell the PKCS11 to initialize itself */ if (priv->init_args != NULL) { memset(&_args, 0, sizeof(_args)); args = &_args; args->pReserved = priv->init_args; } rv = priv->method->C_Initialize(args); if (rv && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) { PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, rv); return -1; } /* Reinitialize the PKCS11 internal slot table */ return pkcs11_enumerate_slots(ctx, NULL, NULL); } /* * Unload the shared library */ void PKCS11_CTX_unload(PKCS11_CTX * ctx) { PKCS11_CTX_private *priv; priv = PRIVCTX(ctx); /* Tell the PKCS11 library to shut down */ if (priv->forkid == _P11_get_forkid()) priv->method->C_Finalize(NULL); /* Unload the module */ C_UnloadModule(handle); } /* * Free a context */ void PKCS11_CTX_free(PKCS11_CTX * ctx) { PKCS11_CTX_private *priv = PRIVCTX(ctx); /* Do not remove the strings since OpenSSL strings may still be used by * the application and we can't know ERR_free_strings(); ERR_remove_state(0); */ if (priv->init_args) { OPENSSL_free(priv->init_args); } pkcs11_destroy_dynlockid(priv->lockid); OPENSSL_free(ctx->manufacturer); OPENSSL_free(ctx->description); OPENSSL_free(ctx->_private); OPENSSL_free(ctx); } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/p11_misc.c000066400000000000000000000105701265040137300162440ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * Copyright (C) 2015 Michał Trojnara * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "libp11-int.h" #include #include /* PKCS11 strings are fixed size blank padded, * so when strduping them we must make sure * we stop at the end of the buffer, and while we're * at it it's nice to remove the padding */ char *pkcs11_strdup(char *mem, size_t size) { char *res; while (size && mem[size - 1] == ' ') size--; res = OPENSSL_malloc(size + 1); if (res == NULL) return NULL; memcpy(res, mem, size); res[size] = '\0'; return res; } /* * Dup memory */ void *memdup(const void *src, size_t size) { void *dst; dst = OPENSSL_malloc(size); if (dst == NULL) return NULL; memcpy(dst, src, size); return dst; } /* * PKCS#11 reinitialization after fork * It wipes out the internal state of the PKCS#11 library * Any libp11 references to this state are no longer valid */ static int check_fork_int(PKCS11_CTX *ctx) { PKCS11_CTX_private *priv = PRIVCTX(ctx); if (_P11_detect_fork(priv->forkid)) { if (PKCS11_CTX_reload(ctx) < 0) return -1; priv->forkid = _P11_get_forkid(); } return 0; } /* * PKCS#11 reinitialization after fork * Also relogins and reopens the session if needed */ static int check_slot_fork_int(PKCS11_SLOT *slot) { PKCS11_SLOT_private *spriv = PRIVSLOT(slot); PKCS11_CTX *ctx = SLOT2CTX(slot); PKCS11_CTX_private *priv = PRIVCTX(ctx); if (check_fork_int(SLOT2CTX(slot)) < 0) return -1; if (spriv->forkid != priv->forkid) { if (spriv->loggedIn) { int saved = spriv->haveSession; spriv->haveSession = 0; spriv->loggedIn = 0; if (PKCS11_relogin(slot) < 0) return -1; spriv->haveSession = saved; } if (spriv->haveSession) { spriv->haveSession = 0; if (PKCS11_reopen_session(slot) < 0) return -1; } spriv->forkid = priv->forkid; } return 0; } /* * PKCS#11 reinitialization after fork * Also reloads the key */ static int check_key_fork_int(PKCS11_KEY *key) { PKCS11_KEY_private *priv = PRIVKEY(key); PKCS11_SLOT *slot = TOKEN2SLOT(priv->parent); PKCS11_SLOT_private *spriv = PRIVSLOT(slot); if (check_slot_fork_int(slot) < 0) return -1; if (spriv->forkid != priv->forkid) { pkcs11_reload_key(key); priv->forkid = spriv->forkid; } return 0; } /* * Locking interface to check_fork_int() */ int check_fork(PKCS11_CTX *ctx) { PKCS11_CTX_private *priv = PRIVCTX(ctx); int rv; pkcs11_w_lock(priv->lockid); rv = check_fork_int(ctx); pkcs11_w_unlock(priv->lockid); return rv; } /* * Locking interface to check_slot_fork_int() */ int check_slot_fork(PKCS11_SLOT *slot) { PKCS11_CTX *ctx = SLOT2CTX(slot); PKCS11_CTX_private *priv = PRIVCTX(ctx); int rv; pkcs11_w_lock(priv->lockid); rv = check_slot_fork_int(slot); pkcs11_w_unlock(priv->lockid); return rv; } /* * Locking interface to check_key_fork_int() */ int check_key_fork(PKCS11_KEY *key) { PKCS11_CTX *ctx = KEY2CTX(key); PKCS11_CTX_private *priv = PRIVCTX(ctx); int rv; CRYPTO_w_lock(priv->lockid); rv = check_key_fork_int(key); CRYPTO_w_unlock(priv->lockid); return rv; } /* * CRYPTO dynlock wrappers: 0 is an invalid dynamic lock ID */ int pkcs11_get_new_dynlockid() { int i; if (CRYPTO_get_dynlock_create_callback() == NULL || CRYPTO_get_dynlock_lock_callback() == NULL || CRYPTO_get_dynlock_destroy_callback() == NULL) return 0; /* Dynamic callbacks not set */ i = CRYPTO_get_new_dynlockid(); if (i == 0) ERR_clear_error(); /* Dynamic locks are optional -> ignore */ return i; } void pkcs11_destroy_dynlockid(int i) { if(i) CRYPTO_destroy_dynlockid(i); } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/p11_ops.c000066400000000000000000000145531265040137300161170ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * Copyright (C) 2005 Kevin Stefanik * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* this file does certain cryptographic operations via the pkcs11 library */ #include "libp11-int.h" #include int PKCS11_ecdsa_sign(const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, PKCS11_KEY * key) { /* signature size is the issue, will assume caller has a big buffer ! */ /* No padding or other stuff needed, we can cal PKCS11 from here */ int rv; PKCS11_KEY_private *priv; PKCS11_SLOT *slot; PKCS11_CTX *ctx; CK_SESSION_HANDLE session; CK_MECHANISM mechanism; CK_ULONG ck_sigsize; ctx = KEY2CTX(key); priv = PRIVKEY(key); slot = TOKEN2SLOT(priv->parent); CHECK_KEY_FORK(key); session = PRIVSLOT(slot)->session; ck_sigsize = *siglen; memset(&mechanism, 0, sizeof(mechanism)); mechanism.mechanism = CKM_ECDSA; pkcs11_w_lock(PRIVSLOT(slot)->lockid); rv = CRYPTOKI_call(ctx, C_SignInit(session, &mechanism, priv->object)) || CRYPTOKI_call(ctx, C_Sign(session, (CK_BYTE *) m, m_len, sigret, &ck_sigsize)); pkcs11_w_unlock(PRIVSLOT(slot)->lockid); if (rv) { PKCS11err(PKCS11_F_PKCS11_EC_KEY_SIGN, pkcs11_map_err(rv)); return -1; } *siglen = ck_sigsize; return ck_sigsize; } /* Following used for RSA */ int PKCS11_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, PKCS11_KEY * key) { int rv, ssl = ((type == NID_md5_sha1) ? 1 : 0); unsigned char *encoded = NULL; int sigsize; if (key == NULL) return 0; CHECK_KEY_FORK(key); sigsize = PKCS11_get_key_size(key); if (ssl) { if ((m_len != 36) /* SHA1 + MD5 */ || ((m_len + RSA_PKCS1_PADDING_SIZE) > (unsigned)sigsize)) { return 0; /* the size is wrong */ } } else { ASN1_TYPE parameter = { V_ASN1_NULL, { NULL } }; ASN1_STRING digest = { m_len, V_ASN1_OCTET_STRING, (unsigned char *)m, 0 }; X509_ALGOR algor = { NULL, ¶meter }; X509_SIG digest_info = { &algor, &digest }; int size; /* Fetch the OID of the algorithm used */ if ((algor.algorithm = OBJ_nid2obj(type)) && (algor.algorithm->length) && /* Get the size of the encoded DigestInfo */ (size = i2d_X509_SIG(&digest_info, NULL)) && /* Check that size is compatible with PKCS#11 padding */ (size + RSA_PKCS1_PADDING_SIZE <= sigsize) && (encoded = OPENSSL_malloc(sigsize))) { unsigned char *tmp = encoded; /* Actually do the encoding */ i2d_X509_SIG(&digest_info,&tmp); m = encoded; m_len = size; } else { return 0; } } rv = PKCS11_private_encrypt(m_len, m, sigret, key, RSA_PKCS1_PADDING); if (rv <= 0) rv = 0; else { *siglen = rv; rv = 1; } if (encoded != NULL) /* NULL on SSL case */ OPENSSL_free(encoded); return rv; } int PKCS11_private_encrypt(int flen, const unsigned char *from, unsigned char *to, PKCS11_KEY * key, int padding) { PKCS11_KEY_private *priv; PKCS11_SLOT *slot; PKCS11_CTX *ctx; CK_SESSION_HANDLE session; CK_MECHANISM mechanism; int rv; int sigsize; CK_ULONG ck_sigsize; if (key == NULL) return -1; sigsize=PKCS11_get_key_size(key); ck_sigsize=sigsize; memset(&mechanism, 0, sizeof(mechanism)); switch (padding) { case RSA_NO_PADDING: mechanism.mechanism = CKM_RSA_X_509; break; case RSA_PKCS1_PADDING: if ((flen + RSA_PKCS1_PADDING_SIZE) > sigsize) { return -1; /* the size is wrong */ } mechanism.mechanism = CKM_RSA_PKCS; break; default: printf("pkcs11 engine: only RSA_NO_PADDING or RSA_PKCS1_PADDING allowed so far\n"); return -1; } ctx = KEY2CTX(key); priv = PRIVKEY(key); slot = TOKEN2SLOT(priv->parent); CHECK_KEY_FORK(key); session = PRIVSLOT(slot)->session; pkcs11_w_lock(PRIVSLOT(slot)->lockid); /* API is somewhat fishy here. *siglen is 0 on entry (cleared * by OpenSSL). The library assumes that the memory passed * by the caller is always big enough */ rv = CRYPTOKI_call(ctx, C_SignInit(session, &mechanism, priv->object)) || CRYPTOKI_call(ctx, C_Sign(session, (CK_BYTE *) from, flen, to, &ck_sigsize)); pkcs11_w_unlock(PRIVSLOT(slot)->lockid); if (rv) { PKCS11err(PKCS11_F_PKCS11_RSA_SIGN, pkcs11_map_err(rv)); return -1; } if ((unsigned)sigsize != ck_sigsize) return -1; return sigsize; } int PKCS11_private_decrypt(int flen, const unsigned char *from, unsigned char *to, PKCS11_KEY * key, int padding) { CK_RV rv; PKCS11_KEY_private *priv; PKCS11_SLOT *slot; PKCS11_CTX *ctx; CK_SESSION_HANDLE session; CK_MECHANISM mechanism; CK_ULONG size = flen; if (padding != RSA_PKCS1_PADDING) { printf("pkcs11 engine: only RSA_PKCS1_PADDING allowed so far\n"); return -1; } if (key == NULL) return -1; /* PKCS11 calls go here */ ctx = KEY2CTX(key); priv = PRIVKEY(key); slot = TOKEN2SLOT(priv->parent); CHECK_KEY_FORK(key); session = PRIVSLOT(slot)->session; memset(&mechanism, 0, sizeof(mechanism)); mechanism.mechanism = CKM_RSA_PKCS; pkcs11_w_lock(PRIVSLOT(slot)->lockid); rv = CRYPTOKI_call(ctx, C_DecryptInit(session, &mechanism, priv->object)) || CRYPTOKI_call(ctx, C_Decrypt(session, (CK_BYTE *) from, (CK_ULONG)flen, (CK_BYTE_PTR)to, &size)); pkcs11_w_unlock(PRIVSLOT(slot)->lockid); if (rv) { PKCS11err(PKCS11_F_PKCS11_RSA_DECRYPT, pkcs11_map_err(rv)); } return rv ? 0 : size; } int PKCS11_verify(int type, const unsigned char *m, unsigned int m_len, unsigned char *signature, unsigned int siglen, PKCS11_KEY * key) { (void)type; (void)m; (void)m_len; (void)signature; (void)siglen; (void)key; /* PKCS11 calls go here */ PKCS11err(PKCS11_F_PKCS11_RSA_VERIFY, PKCS11_NOT_SUPPORTED); return -1; } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/p11_rsa.c000066400000000000000000000143351265040137300161010ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * Copyright (C) 2016 Michał Trojnara * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * This file implements the handling of RSA keys stored on a * PKCS11 token */ #include "libp11-int.h" #include #include #include static int rsa_ex_index = 0; /* * Get RSA key material */ static RSA *pkcs11_get_rsa(PKCS11_KEY * key) { RSA *rsa; PKCS11_KEY *keys = NULL; unsigned int i, count = 0; rsa = RSA_new(); if (rsa == NULL) return NULL; /* Retrieve the modulus and the public exponent */ if (key_getattr_bn(key, CKA_MODULUS, &rsa->n) || key_getattr_bn(key, CKA_PUBLIC_EXPONENT, &rsa->e)) { RSA_free(rsa); return NULL; } if(!BN_is_zero(rsa->e)) /* The public exponent was retrieved */ return rsa; BN_clear_free(rsa->e); /* In case someone modifies this function to execute RSA_free() * before a valid BN value is assigned to rsa->e */ rsa->e = NULL; /* The public exponent was not found in the private key: * retrieve it from the corresponding public key */ if (!PKCS11_enumerate_public_keys(KEY2TOKEN(key), &keys, &count)) { for(i = 0; i < count; i++) { BIGNUM *pubmod; if (key_getattr_bn(&keys[i], CKA_MODULUS, &pubmod)) continue; /* Failed to retrieve the modulus */ if (BN_cmp(rsa->n, pubmod) == 0) { /* The key was found */ BN_clear_free(pubmod); if (key_getattr_bn(&keys[i], CKA_PUBLIC_EXPONENT, &rsa->e)) continue; /* Failed to retrieve the public exponent */ return rsa; } else { BN_clear_free(pubmod); } } } /* Last resort: use the most common default */ rsa->e = BN_new(); if(rsa->e && BN_set_word(rsa->e, RSA_F4)) return rsa; RSA_free(rsa); return NULL; } /* * Build an EVP_PKEY object */ static EVP_PKEY *pkcs11_get_evp_key_rsa(PKCS11_KEY * key) { EVP_PKEY *pk; RSA *rsa; rsa = pkcs11_get_rsa(key); if (rsa == NULL) return NULL; pk = EVP_PKEY_new(); if (pk == NULL) { RSA_free(rsa); return NULL; } EVP_PKEY_set1_RSA(pk, rsa); /* Also increments the rsa ref count */ if (key->isPrivate) RSA_set_method(rsa, PKCS11_get_rsa_method()); /* TODO: Retrieve the RSA private key object attributes instead, * unless the key has the "sensitive" attribute set */ rsa->flags |= RSA_FLAG_SIGN_VER; RSA_set_ex_data(rsa, rsa_ex_index, key); RSA_free(rsa); /* Drops our reference to it */ return pk; } int PKCS11_get_key_modulus(PKCS11_KEY * key, BIGNUM **bn) { if (pkcs11_getattr_bn(KEY2TOKEN(key), PRIVKEY(key)->object, CKA_MODULUS, bn)) return 0; return 1; } int PKCS11_get_key_exponent(PKCS11_KEY * key, BIGNUM **bn) { if (pkcs11_getattr_bn(KEY2TOKEN(key), PRIVKEY(key)->object, CKA_PUBLIC_EXPONENT, bn)) return 0; return 1; } int PKCS11_get_key_size(const PKCS11_KEY * key) { BIGNUM *n = NULL; int numbytes = 0; if (key_getattr_bn(key, CKA_MODULUS, &n)) return 0; numbytes = BN_num_bytes(n); BN_clear_free(n); return numbytes; } static int pkcs11_rsa_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA * rsa, int padding) { return PKCS11_private_decrypt(flen, from, to, (PKCS11_KEY *) RSA_get_ex_data(rsa, rsa_ex_index), padding); } static int pkcs11_rsa_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA * rsa, int padding) { return PKCS11_private_encrypt(flen, from, to, (PKCS11_KEY *) RSA_get_ex_data(rsa, rsa_ex_index), padding); } static int pkcs11_rsa_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, const RSA * rsa) { return PKCS11_sign(type, m, m_len, sigret, siglen, (PKCS11_KEY *) RSA_get_ex_data(rsa, rsa_ex_index)); } /* Lousy hack alert. If RSA_verify detects that the key has the * RSA_FLAG_SIGN_VER flags set, it will assume that verification * is implemented externally as well. * We work around this by temporarily cleaning the flag, and * calling RSA_verify once more. */ static int pkcs11_rsa_verify(int type, const unsigned char *m, unsigned int m_len, const unsigned char *signature, unsigned int siglen, const RSA * rsa) { RSA *r = (RSA *) rsa; /* Ugly hack to get rid of compiler warning */ int res; if (r->flags & RSA_FLAG_SIGN_VER) { r->flags &= ~RSA_FLAG_SIGN_VER; res = RSA_verify(type, m, m_len, signature, siglen, r); r->flags |= RSA_FLAG_SIGN_VER; } else { PKCS11err(PKCS11_F_PKCS11_RSA_VERIFY, PKCS11_NOT_SUPPORTED); res = 0; } return res; } static void alloc_rsa_ex_index() { if (rsa_ex_index == 0) { while (rsa_ex_index == 0) /* Workaround for OpenSSL RT3710 */ rsa_ex_index = RSA_get_ex_new_index(0, "libp11 rsa", NULL, NULL, NULL); if (rsa_ex_index < 0) rsa_ex_index = 0; /* Fallback to app_data */ } } static void free_rsa_ex_index() { /* CRYPTO_free_ex_index requires OpenSSL version >= 1.1.0-pre1 */ #if OPENSSL_VERSION_NUMBER >= 0x10100001L if (rsa_ex_index > 0) { CRYPTO_free_ex_index(CRYPTO_EX_INDEX_RSA, rsa_ex_index); rsa_ex_index = 0; } #endif } /* * Overload the default OpenSSL methods for RSA */ RSA_METHOD *PKCS11_get_rsa_method(void) { static RSA_METHOD ops; alloc_rsa_ex_index(); if (!ops.rsa_priv_enc) { ops = *RSA_get_default_method(); ops.rsa_priv_enc = pkcs11_rsa_encrypt; ops.rsa_priv_dec = pkcs11_rsa_decrypt; ops.rsa_sign = pkcs11_rsa_sign; ops.rsa_verify = pkcs11_rsa_verify; } return &ops; } /* This function is *not* currently exported */ void PKCS11_rsa_method_free(void) { free_rsa_ex_index(); } PKCS11_KEY_ops pkcs11_rsa_ops = { EVP_PKEY_RSA, pkcs11_get_evp_key_rsa }; /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/p11_slot.c000066400000000000000000000342221265040137300162720ustar00rootroot00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "libp11-int.h" #include #include static int pkcs11_init_slot(PKCS11_CTX *, PKCS11_SLOT *, CK_SLOT_ID); static int pkcs11_check_token(PKCS11_CTX *, PKCS11_SLOT *); static void pkcs11_destroy_token(PKCS11_TOKEN *); /* * Get slotid from private */ unsigned long PKCS11_get_slotid_from_slot(PKCS11_SLOT *slot) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); return priv->id; } /* * Enumerate slots */ int PKCS11_enumerate_slots(PKCS11_CTX * ctx, PKCS11_SLOT ** slotp, unsigned int *countp) { CHECK_FORK(ctx); return pkcs11_enumerate_slots(ctx, slotp, countp); } int pkcs11_enumerate_slots(PKCS11_CTX * ctx, PKCS11_SLOT ** slotp, unsigned int *countp) { PKCS11_CTX_private *priv; CK_SLOT_ID *slotid; CK_ULONG nslots, n; PKCS11_SLOT *slots; int rv; priv = PRIVCTX(ctx); rv = priv->method->C_GetSlotList(FALSE, NULL_PTR, &nslots); CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv); slotid = OPENSSL_malloc(nslots * sizeof(CK_SLOT_ID)); if (slotid == NULL) return -1; rv = priv->method->C_GetSlotList(FALSE, slotid, &nslots); CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv); slots = OPENSSL_malloc(nslots * sizeof(PKCS11_SLOT)); if (slots == NULL) return -1; memset(slots, 0, nslots * sizeof(PKCS11_SLOT)); for (n = 0; n < nslots; n++) { if (pkcs11_init_slot(ctx, &slots[n], slotid[n])) { while (n--) pkcs11_release_slot(ctx, slots + n); OPENSSL_free(slotid); OPENSSL_free(slots); return -1; } } if (slotp) *slotp = slots; else OPENSSL_free(slots); if (countp) *countp = nslots; OPENSSL_free(slotid); return 0; } /* * Find a slot with a token that looks "valuable" */ PKCS11_SLOT *PKCS11_find_token(PKCS11_CTX * ctx, PKCS11_SLOT * slots, unsigned int nslots) { PKCS11_SLOT *slot, *best; PKCS11_TOKEN *tok; unsigned int n; (void)ctx; if (slots == NULL) return NULL; best = NULL; for (n = 0, slot = slots; n < nslots; n++, slot++) { if ((tok = slot->token) != NULL) { if (best == NULL || (tok->initialized > best->token->initialized && tok->userPinSet > best->token->userPinSet && tok->loginRequired > best->token->loginRequired)) best = slot; } } return best; } /* * Open a session with this slot */ static int pkcs11_open_session(PKCS11_SLOT * slot, int rw, int relogin) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); PKCS11_CTX *ctx = SLOT2CTX(slot); int rv; if (relogin == 0) { CHECK_SLOT_FORK(slot); if (priv->haveSession) { CRYPTOKI_call(ctx, C_CloseSession(priv->session)); priv->haveSession = 0; } } rv = CRYPTOKI_call(ctx, C_OpenSession(priv->id, CKF_SERIAL_SESSION | (rw ? CKF_RW_SESSION : 0), NULL, NULL, &priv->session)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_OPEN_SESSION, rv); priv->haveSession = 1; priv->prev_rw = rw; return 0; } int PKCS11_open_session(PKCS11_SLOT * slot, int rw) { return pkcs11_open_session(slot, rw, 0); } int PKCS11_reopen_session(PKCS11_SLOT * slot) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); PKCS11_CTX *ctx = SLOT2CTX(slot); int rv; rv = CRYPTOKI_call(ctx, C_OpenSession(priv->id, CKF_SERIAL_SESSION | (priv->prev_rw ? CKF_RW_SESSION : 0), NULL, NULL, &priv->session)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_OPEN_SESSION, rv); priv->haveSession = 1; return 0; } /* * Determines if user is authenticated with token */ int PKCS11_is_logged_in(PKCS11_SLOT * slot, int so, int * res) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); PKCS11_CTX *ctx = priv->parent; CK_SESSION_INFO session_info; int rv; if (priv->loggedIn) { *res = 1; return 0; } if (!priv->haveSession) { /* SO gets a r/w session by default, * user gets a r/o session by default. */ if (PKCS11_open_session(slot, so)) return -1; } rv = CRYPTOKI_call(ctx, C_GetSessionInfo(priv->session, &session_info)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_GETSESSIONINFO, rv); if (so) { *res = session_info.state == CKS_RW_SO_FUNCTIONS; } else { *res = session_info.state == CKS_RO_USER_FUNCTIONS || session_info.state == CKS_RW_USER_FUNCTIONS; } return 0; } /* * Authenticate with the card. relogin should be set if we automatically * relogin after a fork. */ static int pkcs11_login(PKCS11_SLOT * slot, int so, const char *pin, int relogin) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); PKCS11_CTX *ctx = priv->parent; int rv; if (relogin == 0) { CHECK_SLOT_FORK(slot); /* Calling PKCS11_login invalidates all cached * keys we have */ if (slot->token) { pkcs11_destroy_keys(slot->token, CKO_PRIVATE_KEY); pkcs11_destroy_keys(slot->token, CKO_PUBLIC_KEY); } if (priv->loggedIn) { /* already logged in, log out first */ if (PKCS11_logout(slot)) return -1; } } if (!priv->haveSession) { /* SO gets a r/w session by default, * user gets a r/o session by default. */ if (pkcs11_open_session(slot, so, relogin)) return -1; } rv = CRYPTOKI_call(ctx, C_Login(priv->session, so ? CKU_SO : CKU_USER, (CK_UTF8CHAR *) pin, pin ? (unsigned long) strlen(pin) : 0)); if (rv && rv != CKR_USER_ALREADY_LOGGED_IN) /* logged in -> OK */ CRYPTOKI_checkerr(PKCS11_F_PKCS11_LOGIN, rv); priv->loggedIn = 1; if (priv->prev_pin != pin) { if (priv->prev_pin) { OPENSSL_cleanse(priv->prev_pin, strlen(priv->prev_pin)); OPENSSL_free(priv->prev_pin); } priv->prev_pin = BUF_strdup(pin); } priv->prev_so = so; return 0; } /* * Authenticate with the card */ int PKCS11_login(PKCS11_SLOT * slot, int so, const char *pin) { return pkcs11_login(slot, so, pin, 0); } int PKCS11_relogin(PKCS11_SLOT * slot) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); return pkcs11_login(slot, priv->prev_so, priv->prev_pin, 1); } /* * Log out */ int PKCS11_logout(PKCS11_SLOT * slot) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); PKCS11_CTX *ctx = priv->parent; int rv; CHECK_SLOT_FORK(slot); /* Calling PKCS11_logout invalidates all cached * keys we have */ if (slot->token) { pkcs11_destroy_keys(slot->token, CKO_PRIVATE_KEY); pkcs11_destroy_keys(slot->token, CKO_PUBLIC_KEY); } if (!priv->haveSession) { PKCS11err(PKCS11_F_PKCS11_LOGOUT, PKCS11_NO_SESSION); return -1; } rv = CRYPTOKI_call(ctx, C_Logout(priv->session)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_LOGOUT, rv); priv->loggedIn = 0; return 0; } /* * Initialize the token */ int PKCS11_init_token(PKCS11_TOKEN * token, const char *pin, const char *label) { PKCS11_SLOT_private *priv = PRIVSLOT(TOKEN2SLOT(token)); PKCS11_CTX *ctx = priv->parent; int rv; CHECK_FORK(ctx); if (label == NULL) label = "PKCS#11 Token"; rv = CRYPTOKI_call(ctx, C_InitToken(priv->id, (CK_UTF8CHAR *) pin, (unsigned long) strlen(pin), (CK_UTF8CHAR *) label)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_INIT_TOKEN, rv); /* FIXME: how to update the token? * PKCS11_CTX_private *cpriv; * int n; * cpriv = PRIVCTX(ctx); * for (n = 0; n < cpriv->nslots; n++) { * if (pkcs11_check_token(ctx, cpriv->slots + n) < 0) * return -1; * } */ return 0; } /* * Set the User PIN */ int PKCS11_init_pin(PKCS11_TOKEN * token, const char *pin) { PKCS11_SLOT_private *priv = PRIVSLOT(TOKEN2SLOT(token)); PKCS11_CTX *ctx = priv->parent; int len, rv; CHECK_FORK(ctx); if (!priv->haveSession) { PKCS11err(PKCS11_F_PKCS11_INIT_PIN, PKCS11_NO_SESSION); return -1; } len = pin ? (int) strlen(pin) : 0; rv = CRYPTOKI_call(ctx, C_InitPIN(priv->session, (CK_UTF8CHAR *) pin, len)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_INIT_PIN, rv); return pkcs11_check_token(ctx, TOKEN2SLOT(token)); } /* * Change the User PIN */ int PKCS11_change_pin(PKCS11_SLOT * slot, const char *old_pin, const char *new_pin) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); PKCS11_CTX *ctx = priv->parent; int old_len, new_len, rv; CHECK_SLOT_FORK(slot); if (!priv->haveSession) { PKCS11err(PKCS11_F_PKCS11_CHANGE_PIN, PKCS11_NO_SESSION); return -1; } old_len = old_pin ? (int) strlen(old_pin) : 0; new_len = new_pin ? (int) strlen(new_pin) : 0; rv = CRYPTOKI_call(ctx, C_SetPIN(priv->session, (CK_UTF8CHAR *) old_pin, old_len, (CK_UTF8CHAR *) new_pin, new_len)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_CHANGE_PIN, rv); return pkcs11_check_token(ctx, slot); } /* * Seed the random number generator */ int PKCS11_seed_random(PKCS11_SLOT *slot, const unsigned char *s, unsigned int s_len) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); PKCS11_CTX *ctx = priv->parent; int rv; CHECK_SLOT_FORK(slot); if (!priv->haveSession && PKCS11_open_session(slot, 0)) { PKCS11err(PKCS11_F_PKCS11_SEED_RANDOM, PKCS11_NO_SESSION); return -1; } rv = CRYPTOKI_call(ctx, C_SeedRandom(priv->session, (CK_BYTE_PTR) s, s_len)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_SEED_RANDOM, rv); return pkcs11_check_token(ctx, slot); } /* * Generate random numbers */ int PKCS11_generate_random(PKCS11_SLOT *slot, unsigned char *r, unsigned int r_len) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); PKCS11_CTX *ctx = priv->parent; int rv; CHECK_SLOT_FORK(slot); if (!priv->haveSession && PKCS11_open_session(slot, 0)) { PKCS11err(PKCS11_F_PKCS11_GENERATE_RANDOM, PKCS11_NO_SESSION); return -1; } rv = CRYPTOKI_call(ctx, C_GenerateRandom(priv->session, (CK_BYTE_PTR) r, r_len)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_GENERATE_RANDOM, rv); return pkcs11_check_token(ctx, slot); } /* * Helper functions */ static int pkcs11_init_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot, CK_SLOT_ID id) { PKCS11_SLOT_private *priv; CK_SLOT_INFO info; int rv; rv = CRYPTOKI_call(ctx, C_GetSlotInfo(id, &info)); CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv); priv = OPENSSL_malloc(sizeof(PKCS11_SLOT_private)); if (priv == NULL) return -1; memset(priv, 0, sizeof(PKCS11_SLOT_private)); priv->parent = ctx; priv->id = id; priv->forkid = PRIVCTX(ctx)->forkid; priv->prev_rw = 0; priv->prev_pin = NULL; priv->prev_so = 0; priv->lockid = pkcs11_get_new_dynlockid(); slot->description = PKCS11_DUP(info.slotDescription); slot->manufacturer = PKCS11_DUP(info.manufacturerID); slot->removable = (info.flags & CKF_REMOVABLE_DEVICE) ? 1 : 0; slot->_private = priv; if ((info.flags & CKF_TOKEN_PRESENT) && pkcs11_check_token(ctx, slot)) return -1; return 0; } void PKCS11_release_all_slots(PKCS11_CTX * ctx, PKCS11_SLOT *slots, unsigned int nslots) { unsigned int i; for (i=0; i < nslots; i++) pkcs11_release_slot(ctx, &slots[i]); OPENSSL_free(slots); } void pkcs11_release_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); if (priv) { if (priv->prev_pin) { OPENSSL_cleanse(priv->prev_pin, strlen(priv->prev_pin)); OPENSSL_free(priv->prev_pin); } pkcs11_destroy_dynlockid(priv->lockid); CRYPTOKI_call(ctx, C_CloseAllSessions(priv->id)); } OPENSSL_free(slot->_private); OPENSSL_free(slot->description); OPENSSL_free(slot->manufacturer); if (slot->token) { pkcs11_destroy_token(slot->token); OPENSSL_free(slot->token); } memset(slot, 0, sizeof(*slot)); } static int pkcs11_check_token(PKCS11_CTX * ctx, PKCS11_SLOT * slot) { PKCS11_SLOT_private *priv = PRIVSLOT(slot); PKCS11_TOKEN_private *tpriv; CK_TOKEN_INFO info; int rv; if (slot->token) { pkcs11_destroy_token(slot->token); } else { slot->token = OPENSSL_malloc(sizeof(PKCS11_TOKEN)); if (slot->token == NULL) return -1; memset(slot->token, 0, sizeof(PKCS11_TOKEN)); } rv = CRYPTOKI_call(ctx, C_GetTokenInfo(priv->id, &info)); if (rv == CKR_TOKEN_NOT_PRESENT || rv == CKR_TOKEN_NOT_RECOGNIZED) { OPENSSL_free(slot->token); slot->token = NULL; return 0; } CRYPTOKI_checkerr(PKCS11_F_PKCS11_CHECK_TOKEN, rv); /* We have a token */ tpriv = OPENSSL_malloc(sizeof(PKCS11_TOKEN_private)); if (tpriv == NULL) return -1; memset(tpriv, 0, sizeof(PKCS11_TOKEN_private)); tpriv->parent = slot; tpriv->prv.keys = NULL; tpriv->prv.num = -1; tpriv->pub.keys = NULL; tpriv->pub.num = -1; tpriv->ncerts = -1; slot->token->label = PKCS11_DUP(info.label); slot->token->manufacturer = PKCS11_DUP(info.manufacturerID); slot->token->model = PKCS11_DUP(info.model); slot->token->serialnr = PKCS11_DUP(info.serialNumber); slot->token->initialized = (info.flags & CKF_TOKEN_INITIALIZED) ? 1 : 0; slot->token->loginRequired = (info.flags & CKF_LOGIN_REQUIRED) ? 1 : 0; slot->token->secureLogin = (info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ? 1 : 0; slot->token->userPinSet = (info.flags & CKF_USER_PIN_INITIALIZED) ? 1 : 0; slot->token->readOnly = (info.flags & CKF_WRITE_PROTECTED) ? 1 : 0; slot->token->hasRng = (info.flags & CKF_RNG) ? 1 : 0; slot->token->userPinCountLow = (info.flags & CKF_USER_PIN_COUNT_LOW) ? 1 : 0; slot->token->userPinFinalTry = (info.flags & CKF_USER_PIN_FINAL_TRY) ? 1 : 0; slot->token->userPinLocked = (info.flags & CKF_USER_PIN_LOCKED) ? 1 : 0; slot->token->userPinToBeChanged = (info.flags & CKF_USER_PIN_TO_BE_CHANGED) ? 1 : 0; slot->token->soPinCountLow = (info.flags & CKF_SO_PIN_COUNT_LOW) ? 1 : 0; slot->token->soPinFinalTry = (info.flags & CKF_SO_PIN_FINAL_TRY) ? 1 : 0; slot->token->soPinLocked = (info.flags & CKF_SO_PIN_LOCKED) ? 1 : 0; slot->token->soPinToBeChanged = (info.flags & CKF_SO_PIN_TO_BE_CHANGED) ? 1 : 0; slot->token->_private = tpriv; return 0; } static void pkcs11_destroy_token(PKCS11_TOKEN * token) { pkcs11_destroy_keys(token, CKO_PRIVATE_KEY); pkcs11_destroy_keys(token, CKO_PUBLIC_KEY); pkcs11_destroy_certs(token); OPENSSL_free(token->label); OPENSSL_free(token->manufacturer); OPENSSL_free(token->model); OPENSSL_free(token->serialnr); OPENSSL_free(token->_private); memset(token, 0, sizeof(*token)); } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/src/pkcs11.h000066400000000000000000001227031265040137300157410ustar00rootroot00000000000000/* pkcs11.h Copyright 2006, 2007 g10 Code GmbH Copyright 2006 Andreas Jellinghaus This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /* Please submit changes back to the Scute project at http://www.scute.org/ (or send them to marcus@g10code.com), so that they can be picked up by other projects from there as well. */ /* This file is a modified implementation of the PKCS #11 standard by RSA Security Inc. It is mostly a drop-in replacement, with the following change: This header file does not require any macro definitions by the user (like CK_DEFINE_FUNCTION etc). In fact, it defines those macros for you (if useful, some are missing, let me know if you need more). There is an additional API available that does comply better to the GNU coding standard. It can be switched on by defining CRYPTOKI_GNU before including this header file. For this, the following changes are made to the specification: All structure types are changed to a "struct ck_foo" where CK_FOO is the type name in PKCS #11. All non-structure types are changed to ck_foo_t where CK_FOO is the lowercase version of the type name in PKCS #11. The basic types (CK_ULONG et al.) are removed without substitute. All members of structures are modified in the following way: Type indication prefixes are removed, and underscore characters are inserted before words. Then the result is lowercased. Note that function names are still in the original case, as they need for ABI compatibility. CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute. Use . If CRYPTOKI_COMPAT is defined before including this header file, then none of the API changes above take place, and the API is the one defined by the PKCS #11 standard. */ #ifndef PKCS11_H #define PKCS11_H 1 #if defined(__cplusplus) extern "C" { #endif /* The version of cryptoki we implement. The revision is changed with each modification of this file. If you do not use the "official" version of this file, please consider deleting the revision macro (you may use a macro with a different name to keep track of your versions). */ #define CRYPTOKI_VERSION_MAJOR 2 #define CRYPTOKI_VERSION_MINOR 20 #define CRYPTOKI_VERSION_REVISION 6 /* Compatibility interface is default, unless CRYPTOKI_GNU is given. */ #ifndef CRYPTOKI_GNU #ifndef CRYPTOKI_COMPAT #define CRYPTOKI_COMPAT 1 #endif #endif /* System dependencies. */ #if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) /* There is a matching pop below. */ #pragma pack(push, cryptoki, 1) #ifdef CRYPTOKI_EXPORTS #define CK_SPEC __declspec(dllexport) #else #define CK_SPEC __declspec(dllimport) #endif #else #define CK_SPEC #endif #ifdef CRYPTOKI_COMPAT /* If we are in compatibility mode, switch all exposed names to the PKCS #11 variant. There are corresponding #undefs below. */ #define ck_flags_t CK_FLAGS #define ck_version _CK_VERSION #define ck_info _CK_INFO #define cryptoki_version cryptokiVersion #define manufacturer_id manufacturerID #define library_description libraryDescription #define library_version libraryVersion #define ck_notification_t CK_NOTIFICATION #define ck_slot_id_t CK_SLOT_ID #define ck_slot_info _CK_SLOT_INFO #define slot_description slotDescription #define hardware_version hardwareVersion #define firmware_version firmwareVersion #define ck_token_info _CK_TOKEN_INFO #define serial_number serialNumber #define max_session_count ulMaxSessionCount #define session_count ulSessionCount #define max_rw_session_count ulMaxRwSessionCount #define rw_session_count ulRwSessionCount #define max_pin_len ulMaxPinLen #define min_pin_len ulMinPinLen #define total_public_memory ulTotalPublicMemory #define free_public_memory ulFreePublicMemory #define total_private_memory ulTotalPrivateMemory #define free_private_memory ulFreePrivateMemory #define utc_time utcTime #define ck_session_handle_t CK_SESSION_HANDLE #define ck_user_type_t CK_USER_TYPE #define ck_state_t CK_STATE #define ck_session_info _CK_SESSION_INFO #define slot_id slotID #define device_error ulDeviceError #define ck_object_handle_t CK_OBJECT_HANDLE #define ck_object_class_t CK_OBJECT_CLASS #define ck_hw_feature_type_t CK_HW_FEATURE_TYPE #define ck_key_type_t CK_KEY_TYPE #define ck_certificate_type_t CK_CERTIFICATE_TYPE #define ck_attribute_type_t CK_ATTRIBUTE_TYPE #define ck_attribute _CK_ATTRIBUTE #define value pValue #define value_len ulValueLen #define ck_date _CK_DATE #define ck_mechanism_type_t CK_MECHANISM_TYPE #define ck_mechanism _CK_MECHANISM #define parameter pParameter #define parameter_len ulParameterLen #define ck_mechanism_info _CK_MECHANISM_INFO #define min_key_size ulMinKeySize #define max_key_size ulMaxKeySize #define ck_rv_t CK_RV #define ck_notify_t CK_NOTIFY #define ck_function_list _CK_FUNCTION_LIST #define ck_createmutex_t CK_CREATEMUTEX #define ck_destroymutex_t CK_DESTROYMUTEX #define ck_lockmutex_t CK_LOCKMUTEX #define ck_unlockmutex_t CK_UNLOCKMUTEX #define ck_c_initialize_args _CK_C_INITIALIZE_ARGS #define create_mutex CreateMutex #define destroy_mutex DestroyMutex #define lock_mutex LockMutex #define unlock_mutex UnlockMutex #define reserved pReserved #endif /* CRYPTOKI_COMPAT */ typedef unsigned long ck_flags_t; struct ck_version { unsigned char major; unsigned char minor; }; struct ck_info { struct ck_version cryptoki_version; unsigned char manufacturer_id[32]; ck_flags_t flags; unsigned char library_description[32]; struct ck_version library_version; }; typedef unsigned long ck_notification_t; #define CKN_SURRENDER (0) typedef unsigned long ck_slot_id_t; struct ck_slot_info { unsigned char slot_description[64]; unsigned char manufacturer_id[32]; ck_flags_t flags; struct ck_version hardware_version; struct ck_version firmware_version; }; #define CKF_TOKEN_PRESENT (1 << 0) #define CKF_REMOVABLE_DEVICE (1 << 1) #define CKF_HW_SLOT (1 << 2) #define CKF_ARRAY_ATTRIBUTE (1 << 30) struct ck_token_info { unsigned char label[32]; unsigned char manufacturer_id[32]; unsigned char model[16]; unsigned char serial_number[16]; ck_flags_t flags; unsigned long max_session_count; unsigned long session_count; unsigned long max_rw_session_count; unsigned long rw_session_count; unsigned long max_pin_len; unsigned long min_pin_len; unsigned long total_public_memory; unsigned long free_public_memory; unsigned long total_private_memory; unsigned long free_private_memory; struct ck_version hardware_version; struct ck_version firmware_version; unsigned char utc_time[16]; }; #define CKF_RNG (1 << 0) #define CKF_WRITE_PROTECTED (1 << 1) #define CKF_LOGIN_REQUIRED (1 << 2) #define CKF_USER_PIN_INITIALIZED (1 << 3) #define CKF_RESTORE_KEY_NOT_NEEDED (1 << 5) #define CKF_CLOCK_ON_TOKEN (1 << 6) #define CKF_PROTECTED_AUTHENTICATION_PATH (1 << 8) #define CKF_DUAL_CRYPTO_OPERATIONS (1 << 9) #define CKF_TOKEN_INITIALIZED (1 << 10) #define CKF_SECONDARY_AUTHENTICATION (1 << 11) #define CKF_USER_PIN_COUNT_LOW (1 << 16) #define CKF_USER_PIN_FINAL_TRY (1 << 17) #define CKF_USER_PIN_LOCKED (1 << 18) #define CKF_USER_PIN_TO_BE_CHANGED (1 << 19) #define CKF_SO_PIN_COUNT_LOW (1 << 20) #define CKF_SO_PIN_FINAL_TRY (1 << 21) #define CKF_SO_PIN_LOCKED (1 << 22) #define CKF_SO_PIN_TO_BE_CHANGED (1 << 23) #define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1) #define CK_EFFECTIVELY_INFINITE (0) typedef unsigned long ck_session_handle_t; #define CK_INVALID_HANDLE (0) typedef unsigned long ck_user_type_t; #define CKU_SO (0) #define CKU_USER (1) #define CKU_CONTEXT_SPECIFIC (2) typedef unsigned long ck_state_t; #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) struct ck_session_info { ck_slot_id_t slot_id; ck_state_t state; ck_flags_t flags; unsigned long device_error; }; #define CKF_RW_SESSION (1 << 1) #define CKF_SERIAL_SESSION (1 << 2) typedef unsigned long ck_object_handle_t; typedef unsigned long ck_object_class_t; #define CKO_DATA (0) #define CKO_CERTIFICATE (1) #define CKO_PUBLIC_KEY (2) #define CKO_PRIVATE_KEY (3) #define CKO_SECRET_KEY (4) #define CKO_HW_FEATURE (5) #define CKO_DOMAIN_PARAMETERS (6) #define CKO_MECHANISM (7) #define CKO_VENDOR_DEFINED ((unsigned long) (1 << 31)) typedef unsigned long ck_hw_feature_type_t; #define CKH_MONOTONIC_COUNTER (1) #define CKH_CLOCK (2) #define CKH_USER_INTERFACE (3) #define CKH_VENDOR_DEFINED ((unsigned long) (1 << 31)) typedef unsigned long ck_key_type_t; #define CKK_RSA (0) #define CKK_DSA (1) #define CKK_DH (2) #define CKK_ECDSA (3) #define CKK_EC (3) #define CKK_X9_42_DH (4) #define CKK_KEA (5) #define CKK_GENERIC_SECRET (0x10) #define CKK_RC2 (0x11) #define CKK_RC4 (0x12) #define CKK_DES (0x13) #define CKK_DES2 (0x14) #define CKK_DES3 (0x15) #define CKK_CAST (0x16) #define CKK_CAST3 (0x17) #define CKK_CAST128 (0x18) #define CKK_RC5 (0x19) #define CKK_IDEA (0x1a) #define CKK_SKIPJACK (0x1b) #define CKK_BATON (0x1c) #define CKK_JUNIPER (0x1d) #define CKK_CDMF (0x1e) #define CKK_AES (0x1f) #define CKK_BLOWFISH (0x20) #define CKK_TWOFISH (0x21) #define CKK_VENDOR_DEFINED ((unsigned long) (1 << 31)) typedef unsigned long ck_certificate_type_t; #define CKC_X_509 (0) #define CKC_X_509_ATTR_CERT (1) #define CKC_WTLS (2) #define CKC_VENDOR_DEFINED ((unsigned long) (1 << 31)) typedef unsigned long ck_attribute_type_t; #define CKA_CLASS (0) #define CKA_TOKEN (1) #define CKA_PRIVATE (2) #define CKA_LABEL (3) #define CKA_APPLICATION (0x10) #define CKA_VALUE (0x11) #define CKA_OBJECT_ID (0x12) #define CKA_CERTIFICATE_TYPE (0x80) #define CKA_ISSUER (0x81) #define CKA_SERIAL_NUMBER (0x82) #define CKA_AC_ISSUER (0x83) #define CKA_OWNER (0x84) #define CKA_ATTR_TYPES (0x85) #define CKA_TRUSTED (0x86) #define CKA_CERTIFICATE_CATEGORY (0x87) #define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88) #define CKA_URL (0x89) #define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8a) #define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8b) #define CKA_CHECK_VALUE (0x90) #define CKA_KEY_TYPE (0x100) #define CKA_SUBJECT (0x101) #define CKA_ID (0x102) #define CKA_SENSITIVE (0x103) #define CKA_ENCRYPT (0x104) #define CKA_DECRYPT (0x105) #define CKA_WRAP (0x106) #define CKA_UNWRAP (0x107) #define CKA_SIGN (0x108) #define CKA_SIGN_RECOVER (0x109) #define CKA_VERIFY (0x10a) #define CKA_VERIFY_RECOVER (0x10b) #define CKA_DERIVE (0x10c) #define CKA_START_DATE (0x110) #define CKA_END_DATE (0x111) #define CKA_MODULUS (0x120) #define CKA_MODULUS_BITS (0x121) #define CKA_PUBLIC_EXPONENT (0x122) #define CKA_PRIVATE_EXPONENT (0x123) #define CKA_PRIME_1 (0x124) #define CKA_PRIME_2 (0x125) #define CKA_EXPONENT_1 (0x126) #define CKA_EXPONENT_2 (0x127) #define CKA_COEFFICIENT (0x128) #define CKA_PRIME (0x130) #define CKA_SUBPRIME (0x131) #define CKA_BASE (0x132) #define CKA_PRIME_BITS (0x133) #define CKA_SUB_PRIME_BITS (0x134) #define CKA_VALUE_BITS (0x160) #define CKA_VALUE_LEN (0x161) #define CKA_EXTRACTABLE (0x162) #define CKA_LOCAL (0x163) #define CKA_NEVER_EXTRACTABLE (0x164) #define CKA_ALWAYS_SENSITIVE (0x165) #define CKA_KEY_GEN_MECHANISM (0x166) #define CKA_MODIFIABLE (0x170) #define CKA_ECDSA_PARAMS (0x180) #define CKA_EC_PARAMS (0x180) #define CKA_EC_POINT (0x181) #define CKA_SECONDARY_AUTH (0x200) #define CKA_AUTH_PIN_FLAGS (0x201) #define CKA_ALWAYS_AUTHENTICATE (0x202) #define CKA_WRAP_WITH_TRUSTED (0x210) #define CKA_HW_FEATURE_TYPE (0x300) #define CKA_RESET_ON_INIT (0x301) #define CKA_HAS_RESET (0x302) #define CKA_PIXEL_X (0x400) #define CKA_PIXEL_Y (0x401) #define CKA_RESOLUTION (0x402) #define CKA_CHAR_ROWS (0x403) #define CKA_CHAR_COLUMNS (0x404) #define CKA_COLOR (0x405) #define CKA_BITS_PER_PIXEL (0x406) #define CKA_CHAR_SETS (0x480) #define CKA_ENCODING_METHODS (0x481) #define CKA_MIME_TYPES (0x482) #define CKA_MECHANISM_TYPE (0x500) #define CKA_REQUIRED_CMS_ATTRIBUTES (0x501) #define CKA_DEFAULT_CMS_ATTRIBUTES (0x502) #define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503) #define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211) #define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212) #define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600) #define CKA_VENDOR_DEFINED ((unsigned long) (1 << 31)) struct ck_attribute { ck_attribute_type_t type; void *value; size_t value_len; }; struct ck_date { unsigned char year[4]; unsigned char month[2]; unsigned char day[2]; }; typedef unsigned long ck_mechanism_type_t; #define CKM_RSA_PKCS_KEY_PAIR_GEN (0) #define CKM_RSA_PKCS (1) #define CKM_RSA_9796 (2) #define CKM_RSA_X_509 (3) #define CKM_MD2_RSA_PKCS (4) #define CKM_MD5_RSA_PKCS (5) #define CKM_SHA1_RSA_PKCS (6) #define CKM_RIPEMD128_RSA_PKCS (7) #define CKM_RIPEMD160_RSA_PKCS (8) #define CKM_RSA_PKCS_OAEP (9) #define CKM_RSA_X9_31_KEY_PAIR_GEN (0xa) #define CKM_RSA_X9_31 (0xb) #define CKM_SHA1_RSA_X9_31 (0xc) #define CKM_RSA_PKCS_PSS (0xd) #define CKM_SHA1_RSA_PKCS_PSS (0xe) #define CKM_DSA_KEY_PAIR_GEN (0x10) #define CKM_DSA (0x11) #define CKM_DSA_SHA1 (0x12) #define CKM_DH_PKCS_KEY_PAIR_GEN (0x20) #define CKM_DH_PKCS_DERIVE (0x21) #define CKM_X9_42_DH_KEY_PAIR_GEN (0x30) #define CKM_X9_42_DH_DERIVE (0x31) #define CKM_X9_42_DH_HYBRID_DERIVE (0x32) #define CKM_X9_42_MQV_DERIVE (0x33) #define CKM_SHA256_RSA_PKCS (0x40) #define CKM_SHA384_RSA_PKCS (0x41) #define CKM_SHA512_RSA_PKCS (0x42) #define CKM_SHA256_RSA_PKCS_PSS (0x43) #define CKM_SHA384_RSA_PKCS_PSS (0x44) #define CKM_SHA512_RSA_PKCS_PSS (0x45) #define CKM_RC2_KEY_GEN (0x100) #define CKM_RC2_ECB (0x101) #define CKM_RC2_CBC (0x102) #define CKM_RC2_MAC (0x103) #define CKM_RC2_MAC_GENERAL (0x104) #define CKM_RC2_CBC_PAD (0x105) #define CKM_RC4_KEY_GEN (0x110) #define CKM_RC4 (0x111) #define CKM_DES_KEY_GEN (0x120) #define CKM_DES_ECB (0x121) #define CKM_DES_CBC (0x122) #define CKM_DES_MAC (0x123) #define CKM_DES_MAC_GENERAL (0x124) #define CKM_DES_CBC_PAD (0x125) #define CKM_DES2_KEY_GEN (0x130) #define CKM_DES3_KEY_GEN (0x131) #define CKM_DES3_ECB (0x132) #define CKM_DES3_CBC (0x133) #define CKM_DES3_MAC (0x134) #define CKM_DES3_MAC_GENERAL (0x135) #define CKM_DES3_CBC_PAD (0x136) #define CKM_CDMF_KEY_GEN (0x140) #define CKM_CDMF_ECB (0x141) #define CKM_CDMF_CBC (0x142) #define CKM_CDMF_MAC (0x143) #define CKM_CDMF_MAC_GENERAL (0x144) #define CKM_CDMF_CBC_PAD (0x145) #define CKM_MD2 (0x200) #define CKM_MD2_HMAC (0x201) #define CKM_MD2_HMAC_GENERAL (0x202) #define CKM_MD5 (0x210) #define CKM_MD5_HMAC (0x211) #define CKM_MD5_HMAC_GENERAL (0x212) #define CKM_SHA_1 (0x220) #define CKM_SHA_1_HMAC (0x221) #define CKM_SHA_1_HMAC_GENERAL (0x222) #define CKM_RIPEMD128 (0x230) #define CKM_RIPEMD128_HMAC (0x231) #define CKM_RIPEMD128_HMAC_GENERAL (0x232) #define CKM_RIPEMD160 (0x240) #define CKM_RIPEMD160_HMAC (0x241) #define CKM_RIPEMD160_HMAC_GENERAL (0x242) #define CKM_SHA256 (0x250) #define CKM_SHA256_HMAC (0x251) #define CKM_SHA256_HMAC_GENERAL (0x252) #define CKM_SHA384 (0x260) #define CKM_SHA384_HMAC (0x261) #define CKM_SHA384_HMAC_GENERAL (0x262) #define CKM_SHA512 (0x270) #define CKM_SHA512_HMAC (0x271) #define CKM_SHA512_HMAC_GENERAL (0x272) #define CKM_CAST_KEY_GEN (0x300) #define CKM_CAST_ECB (0x301) #define CKM_CAST_CBC (0x302) #define CKM_CAST_MAC (0x303) #define CKM_CAST_MAC_GENERAL (0x304) #define CKM_CAST_CBC_PAD (0x305) #define CKM_CAST3_KEY_GEN (0x310) #define CKM_CAST3_ECB (0x311) #define CKM_CAST3_CBC (0x312) #define CKM_CAST3_MAC (0x313) #define CKM_CAST3_MAC_GENERAL (0x314) #define CKM_CAST3_CBC_PAD (0x315) #define CKM_CAST5_KEY_GEN (0x320) #define CKM_CAST128_KEY_GEN (0x320) #define CKM_CAST5_ECB (0x321) #define CKM_CAST128_ECB (0x321) #define CKM_CAST5_CBC (0x322) #define CKM_CAST128_CBC (0x322) #define CKM_CAST5_MAC (0x323) #define CKM_CAST128_MAC (0x323) #define CKM_CAST5_MAC_GENERAL (0x324) #define CKM_CAST128_MAC_GENERAL (0x324) #define CKM_CAST5_CBC_PAD (0x325) #define CKM_CAST128_CBC_PAD (0x325) #define CKM_RC5_KEY_GEN (0x330) #define CKM_RC5_ECB (0x331) #define CKM_RC5_CBC (0x332) #define CKM_RC5_MAC (0x333) #define CKM_RC5_MAC_GENERAL (0x334) #define CKM_RC5_CBC_PAD (0x335) #define CKM_IDEA_KEY_GEN (0x340) #define CKM_IDEA_ECB (0x341) #define CKM_IDEA_CBC (0x342) #define CKM_IDEA_MAC (0x343) #define CKM_IDEA_MAC_GENERAL (0x344) #define CKM_IDEA_CBC_PAD (0x345) #define CKM_GENERIC_SECRET_KEY_GEN (0x350) #define CKM_CONCATENATE_BASE_AND_KEY (0x360) #define CKM_CONCATENATE_BASE_AND_DATA (0x362) #define CKM_CONCATENATE_DATA_AND_BASE (0x363) #define CKM_XOR_BASE_AND_DATA (0x364) #define CKM_EXTRACT_KEY_FROM_KEY (0x365) #define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370) #define CKM_SSL3_MASTER_KEY_DERIVE (0x371) #define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372) #define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373) #define CKM_TLS_PRE_MASTER_KEY_GEN (0x374) #define CKM_TLS_MASTER_KEY_DERIVE (0x375) #define CKM_TLS_KEY_AND_MAC_DERIVE (0x376) #define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377) #define CKM_SSL3_MD5_MAC (0x380) #define CKM_SSL3_SHA1_MAC (0x381) #define CKM_MD5_KEY_DERIVATION (0x390) #define CKM_MD2_KEY_DERIVATION (0x391) #define CKM_SHA1_KEY_DERIVATION (0x392) #define CKM_PBE_MD2_DES_CBC (0x3a0) #define CKM_PBE_MD5_DES_CBC (0x3a1) #define CKM_PBE_MD5_CAST_CBC (0x3a2) #define CKM_PBE_MD5_CAST3_CBC (0x3a3) #define CKM_PBE_MD5_CAST5_CBC (0x3a4) #define CKM_PBE_MD5_CAST128_CBC (0x3a4) #define CKM_PBE_SHA1_CAST5_CBC (0x3a5) #define CKM_PBE_SHA1_CAST128_CBC (0x3a5) #define CKM_PBE_SHA1_RC4_128 (0x3a6) #define CKM_PBE_SHA1_RC4_40 (0x3a7) #define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8) #define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9) #define CKM_PBE_SHA1_RC2_128_CBC (0x3aa) #define CKM_PBE_SHA1_RC2_40_CBC (0x3ab) #define CKM_PKCS5_PBKD2 (0x3b0) #define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0) #define CKM_KEY_WRAP_LYNKS (0x400) #define CKM_KEY_WRAP_SET_OAEP (0x401) #define CKM_SKIPJACK_KEY_GEN (0x1000) #define CKM_SKIPJACK_ECB64 (0x1001) #define CKM_SKIPJACK_CBC64 (0x1002) #define CKM_SKIPJACK_OFB64 (0x1003) #define CKM_SKIPJACK_CFB64 (0x1004) #define CKM_SKIPJACK_CFB32 (0x1005) #define CKM_SKIPJACK_CFB16 (0x1006) #define CKM_SKIPJACK_CFB8 (0x1007) #define CKM_SKIPJACK_WRAP (0x1008) #define CKM_SKIPJACK_PRIVATE_WRAP (0x1009) #define CKM_SKIPJACK_RELAYX (0x100a) #define CKM_KEA_KEY_PAIR_GEN (0x1010) #define CKM_KEA_KEY_DERIVE (0x1011) #define CKM_FORTEZZA_TIMESTAMP (0x1020) #define CKM_BATON_KEY_GEN (0x1030) #define CKM_BATON_ECB128 (0x1031) #define CKM_BATON_ECB96 (0x1032) #define CKM_BATON_CBC128 (0x1033) #define CKM_BATON_COUNTER (0x1034) #define CKM_BATON_SHUFFLE (0x1035) #define CKM_BATON_WRAP (0x1036) #define CKM_ECDSA_KEY_PAIR_GEN (0x1040) #define CKM_EC_KEY_PAIR_GEN (0x1040) #define CKM_ECDSA (0x1041) #define CKM_ECDSA_SHA1 (0x1042) #define CKM_ECDH1_DERIVE (0x1050) #define CKM_ECDH1_COFACTOR_DERIVE (0x1051) #define CKM_ECMQV_DERIVE (0x1052) #define CKM_JUNIPER_KEY_GEN (0x1060) #define CKM_JUNIPER_ECB128 (0x1061) #define CKM_JUNIPER_CBC128 (0x1062) #define CKM_JUNIPER_COUNTER (0x1063) #define CKM_JUNIPER_SHUFFLE (0x1064) #define CKM_JUNIPER_WRAP (0x1065) #define CKM_FASTHASH (0x1070) #define CKM_AES_KEY_GEN (0x1080) #define CKM_AES_ECB (0x1081) #define CKM_AES_CBC (0x1082) #define CKM_AES_MAC (0x1083) #define CKM_AES_MAC_GENERAL (0x1084) #define CKM_AES_CBC_PAD (0x1085) #define CKM_DSA_PARAMETER_GEN (0x2000) #define CKM_DH_PKCS_PARAMETER_GEN (0x2001) #define CKM_X9_42_DH_PARAMETER_GEN (0x2002) #define CKM_VENDOR_DEFINED ((unsigned long) (1 << 31)) struct ck_mechanism { ck_mechanism_type_t mechanism; void *parameter; unsigned long parameter_len; }; struct ck_mechanism_info { unsigned long min_key_size; unsigned long max_key_size; ck_flags_t flags; }; #define CKF_HW (1 << 0) #define CKF_ENCRYPT (1 << 8) #define CKF_DECRYPT (1 << 9) #define CKF_DIGEST (1 << 10) #define CKF_SIGN (1 << 11) #define CKF_SIGN_RECOVER (1 << 12) #define CKF_VERIFY (1 << 13) #define CKF_VERIFY_RECOVER (1 << 14) #define CKF_GENERATE (1 << 15) #define CKF_GENERATE_KEY_PAIR (1 << 16) #define CKF_WRAP (1 << 17) #define CKF_UNWRAP (1 << 18) #define CKF_DERIVE (1 << 19) #define CKF_EXTENSION ((unsigned long) (1 << 31)) /* Flags for C_WaitForSlotEvent. */ #define CKF_DONT_BLOCK (1) typedef unsigned long ck_rv_t; typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session, ck_notification_t event, void *application); /* Forward reference. */ struct ck_function_list; #define _CK_DECLARE_FUNCTION(name, args) \ typedef ck_rv_t (*CK_ ## name) args; \ ck_rv_t CK_SPEC name args _CK_DECLARE_FUNCTION (C_Initialize, (void *init_args)); _CK_DECLARE_FUNCTION (C_Finalize, (void *reserved)); _CK_DECLARE_FUNCTION (C_GetInfo, (struct ck_info *info)); _CK_DECLARE_FUNCTION (C_GetFunctionList, (struct ck_function_list **function_list)); _CK_DECLARE_FUNCTION (C_GetSlotList, (unsigned char token_present, ck_slot_id_t *slot_list, unsigned long *count)); _CK_DECLARE_FUNCTION (C_GetSlotInfo, (ck_slot_id_t slot_id, struct ck_slot_info *info)); _CK_DECLARE_FUNCTION (C_GetTokenInfo, (ck_slot_id_t slot_id, struct ck_token_info *info)); _CK_DECLARE_FUNCTION (C_WaitForSlotEvent, (ck_flags_t flags, ck_slot_id_t *slot, void *reserved)); _CK_DECLARE_FUNCTION (C_GetMechanismList, (ck_slot_id_t slot_id, ck_mechanism_type_t *mechanism_list, unsigned long *count)); _CK_DECLARE_FUNCTION (C_GetMechanismInfo, (ck_slot_id_t slot_id, ck_mechanism_type_t type, struct ck_mechanism_info *info)); _CK_DECLARE_FUNCTION (C_InitToken, (ck_slot_id_t slot_id, unsigned char *pin, unsigned long pin_len, unsigned char *label)); _CK_DECLARE_FUNCTION (C_InitPIN, (ck_session_handle_t session, unsigned char *pin, unsigned long pin_len)); _CK_DECLARE_FUNCTION (C_SetPIN, (ck_session_handle_t session, unsigned char *old_pin, unsigned long old_len, unsigned char *new_pin, unsigned long new_len)); _CK_DECLARE_FUNCTION (C_OpenSession, (ck_slot_id_t slot_id, ck_flags_t flags, void *application, ck_notify_t notify, ck_session_handle_t *session)); _CK_DECLARE_FUNCTION (C_CloseSession, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CloseAllSessions, (ck_slot_id_t slot_id)); _CK_DECLARE_FUNCTION (C_GetSessionInfo, (ck_session_handle_t session, struct ck_session_info *info)); _CK_DECLARE_FUNCTION (C_GetOperationState, (ck_session_handle_t session, unsigned char *operation_state, unsigned long *operation_state_len)); _CK_DECLARE_FUNCTION (C_SetOperationState, (ck_session_handle_t session, unsigned char *operation_state, unsigned long operation_state_len, ck_object_handle_t encryption_key, ck_object_handle_t authentiation_key)); _CK_DECLARE_FUNCTION (C_Login, (ck_session_handle_t session, ck_user_type_t user_type, unsigned char *pin, unsigned long pin_len)); _CK_DECLARE_FUNCTION (C_Logout, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CreateObject, (ck_session_handle_t session, struct ck_attribute *templ, unsigned long count, ck_object_handle_t *object)); _CK_DECLARE_FUNCTION (C_CopyObject, (ck_session_handle_t session, ck_object_handle_t object, struct ck_attribute *templ, unsigned long count, ck_object_handle_t *new_object)); _CK_DECLARE_FUNCTION (C_DestroyObject, (ck_session_handle_t session, ck_object_handle_t object)); _CK_DECLARE_FUNCTION (C_GetObjectSize, (ck_session_handle_t session, ck_object_handle_t object, unsigned long *size)); _CK_DECLARE_FUNCTION (C_GetAttributeValue, (ck_session_handle_t session, ck_object_handle_t object, struct ck_attribute *templ, unsigned long count)); _CK_DECLARE_FUNCTION (C_SetAttributeValue, (ck_session_handle_t session, ck_object_handle_t object, struct ck_attribute *templ, unsigned long count)); _CK_DECLARE_FUNCTION (C_FindObjectsInit, (ck_session_handle_t session, struct ck_attribute *templ, unsigned long count)); _CK_DECLARE_FUNCTION (C_FindObjects, (ck_session_handle_t session, ck_object_handle_t *object, unsigned long max_object_count, unsigned long *object_count)); _CK_DECLARE_FUNCTION (C_FindObjectsFinal, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_EncryptInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Encrypt, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *encrypted_data, unsigned long *encrypted_data_len)); _CK_DECLARE_FUNCTION (C_EncryptUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len, unsigned char *encrypted_part, unsigned long *encrypted_part_len)); _CK_DECLARE_FUNCTION (C_EncryptFinal, (ck_session_handle_t session, unsigned char *last_encrypted_part, unsigned long *last_encrypted_part_len)); _CK_DECLARE_FUNCTION (C_DecryptInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Decrypt, (ck_session_handle_t session, unsigned char *encrypted_data, unsigned long encrypted_data_len, unsigned char *data, unsigned long *data_len)); _CK_DECLARE_FUNCTION (C_DecryptUpdate, (ck_session_handle_t session, unsigned char *encrypted_part, unsigned long encrypted_part_len, unsigned char *part, unsigned long *part_len)); _CK_DECLARE_FUNCTION (C_DecryptFinal, (ck_session_handle_t session, unsigned char *last_part, unsigned long *last_part_len)); _CK_DECLARE_FUNCTION (C_DigestInit, (ck_session_handle_t session, struct ck_mechanism *mechanism)); _CK_DECLARE_FUNCTION (C_Digest, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *digest, unsigned long *digest_len)); _CK_DECLARE_FUNCTION (C_DigestUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len)); _CK_DECLARE_FUNCTION (C_DigestKey, (ck_session_handle_t session, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_DigestFinal, (ck_session_handle_t session, unsigned char *digest, unsigned long *digest_len)); _CK_DECLARE_FUNCTION (C_SignInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Sign, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *signature, unsigned long *signature_len)); _CK_DECLARE_FUNCTION (C_SignUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len)); _CK_DECLARE_FUNCTION (C_SignFinal, (ck_session_handle_t session, unsigned char *signature, unsigned long *signature_len)); _CK_DECLARE_FUNCTION (C_SignRecoverInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_SignRecover, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *signature, unsigned long *signature_len)); _CK_DECLARE_FUNCTION (C_VerifyInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Verify, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *signature, unsigned long signature_len)); _CK_DECLARE_FUNCTION (C_VerifyUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len)); _CK_DECLARE_FUNCTION (C_VerifyFinal, (ck_session_handle_t session, unsigned char *signature, unsigned long signature_len)); _CK_DECLARE_FUNCTION (C_VerifyRecoverInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_VerifyRecover, (ck_session_handle_t session, unsigned char *signature, unsigned long signature_len, unsigned char *data, unsigned long *data_len)); _CK_DECLARE_FUNCTION (C_DigestEncryptUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len, unsigned char *encrypted_part, unsigned long *encrypted_part_len)); _CK_DECLARE_FUNCTION (C_DecryptDigestUpdate, (ck_session_handle_t session, unsigned char *encrypted_part, unsigned long encrypted_part_len, unsigned char *part, unsigned long *part_len)); _CK_DECLARE_FUNCTION (C_SignEncryptUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len, unsigned char *encrypted_part, unsigned long *encrypted_part_len)); _CK_DECLARE_FUNCTION (C_DecryptVerifyUpdate, (ck_session_handle_t session, unsigned char *encrypted_part, unsigned long encrypted_part_len, unsigned char *part, unsigned long *part_len)); _CK_DECLARE_FUNCTION (C_GenerateKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, struct ck_attribute *templ, unsigned long count, ck_object_handle_t *key)); _CK_DECLARE_FUNCTION (C_GenerateKeyPair, (ck_session_handle_t session, struct ck_mechanism *mechanism, struct ck_attribute *public_key_template, unsigned long public_key_attribute_count, struct ck_attribute *private_key_template, unsigned long private_key_attribute_count, ck_object_handle_t *public_key, ck_object_handle_t *private_key)); _CK_DECLARE_FUNCTION (C_WrapKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t wrapping_key, ck_object_handle_t key, unsigned char *wrapped_key, unsigned long *wrapped_key_len)); _CK_DECLARE_FUNCTION (C_UnwrapKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t unwrapping_key, unsigned char *wrapped_key, unsigned long wrapped_key_len, struct ck_attribute *templ, unsigned long attribute_count, ck_object_handle_t *key)); _CK_DECLARE_FUNCTION (C_DeriveKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t base_key, struct ck_attribute *templ, unsigned long attribute_count, ck_object_handle_t *key)); _CK_DECLARE_FUNCTION (C_SeedRandom, (ck_session_handle_t session, unsigned char *seed, unsigned long seed_len)); _CK_DECLARE_FUNCTION (C_GenerateRandom, (ck_session_handle_t session, unsigned char *random_data, unsigned long random_len)); _CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session)); struct ck_function_list { struct ck_version version; CK_C_Initialize C_Initialize; CK_C_Finalize C_Finalize; CK_C_GetInfo C_GetInfo; CK_C_GetFunctionList C_GetFunctionList; CK_C_GetSlotList C_GetSlotList; CK_C_GetSlotInfo C_GetSlotInfo; CK_C_GetTokenInfo C_GetTokenInfo; CK_C_GetMechanismList C_GetMechanismList; CK_C_GetMechanismInfo C_GetMechanismInfo; CK_C_InitToken C_InitToken; CK_C_InitPIN C_InitPIN; CK_C_SetPIN C_SetPIN; CK_C_OpenSession C_OpenSession; CK_C_CloseSession C_CloseSession; CK_C_CloseAllSessions C_CloseAllSessions; CK_C_GetSessionInfo C_GetSessionInfo; CK_C_GetOperationState C_GetOperationState; CK_C_SetOperationState C_SetOperationState; CK_C_Login C_Login; CK_C_Logout C_Logout; CK_C_CreateObject C_CreateObject; CK_C_CopyObject C_CopyObject; CK_C_DestroyObject C_DestroyObject; CK_C_GetObjectSize C_GetObjectSize; CK_C_GetAttributeValue C_GetAttributeValue; CK_C_SetAttributeValue C_SetAttributeValue; CK_C_FindObjectsInit C_FindObjectsInit; CK_C_FindObjects C_FindObjects; CK_C_FindObjectsFinal C_FindObjectsFinal; CK_C_EncryptInit C_EncryptInit; CK_C_Encrypt C_Encrypt; CK_C_EncryptUpdate C_EncryptUpdate; CK_C_EncryptFinal C_EncryptFinal; CK_C_DecryptInit C_DecryptInit; CK_C_Decrypt C_Decrypt; CK_C_DecryptUpdate C_DecryptUpdate; CK_C_DecryptFinal C_DecryptFinal; CK_C_DigestInit C_DigestInit; CK_C_Digest C_Digest; CK_C_DigestUpdate C_DigestUpdate; CK_C_DigestKey C_DigestKey; CK_C_DigestFinal C_DigestFinal; CK_C_SignInit C_SignInit; CK_C_Sign C_Sign; CK_C_SignUpdate C_SignUpdate; CK_C_SignFinal C_SignFinal; CK_C_SignRecoverInit C_SignRecoverInit; CK_C_SignRecover C_SignRecover; CK_C_VerifyInit C_VerifyInit; CK_C_Verify C_Verify; CK_C_VerifyUpdate C_VerifyUpdate; CK_C_VerifyFinal C_VerifyFinal; CK_C_VerifyRecoverInit C_VerifyRecoverInit; CK_C_VerifyRecover C_VerifyRecover; CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; CK_C_SignEncryptUpdate C_SignEncryptUpdate; CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; CK_C_GenerateKey C_GenerateKey; CK_C_GenerateKeyPair C_GenerateKeyPair; CK_C_WrapKey C_WrapKey; CK_C_UnwrapKey C_UnwrapKey; CK_C_DeriveKey C_DeriveKey; CK_C_SeedRandom C_SeedRandom; CK_C_GenerateRandom C_GenerateRandom; CK_C_GetFunctionStatus C_GetFunctionStatus; CK_C_CancelFunction C_CancelFunction; CK_C_WaitForSlotEvent C_WaitForSlotEvent; }; typedef ck_rv_t (*ck_createmutex_t) (void **mutex); typedef ck_rv_t (*ck_destroymutex_t) (void *mutex); typedef ck_rv_t (*ck_lockmutex_t) (void *mutex); typedef ck_rv_t (*ck_unlockmutex_t) (void *mutex); struct ck_c_initialize_args { ck_createmutex_t create_mutex; ck_destroymutex_t destroy_mutex; ck_lockmutex_t lock_mutex; ck_unlockmutex_t unlock_mutex; ck_flags_t flags; void *reserved; }; #define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1 << 0) #define CKF_OS_LOCKING_OK (1 << 1) #define CKR_OK (0) #define CKR_CANCEL (1) #define CKR_HOST_MEMORY (2) #define CKR_SLOT_ID_INVALID (3) #define CKR_GENERAL_ERROR (5) #define CKR_FUNCTION_FAILED (6) #define CKR_ARGUMENTS_BAD (7) #define CKR_NO_EVENT (8) #define CKR_NEED_TO_CREATE_THREADS (9) #define CKR_CANT_LOCK (0xa) #define CKR_ATTRIBUTE_READ_ONLY (0x10) #define CKR_ATTRIBUTE_SENSITIVE (0x11) #define CKR_ATTRIBUTE_TYPE_INVALID (0x12) #define CKR_ATTRIBUTE_VALUE_INVALID (0x13) #define CKR_DATA_INVALID (0x20) #define CKR_DATA_LEN_RANGE (0x21) #define CKR_DEVICE_ERROR (0x30) #define CKR_DEVICE_MEMORY (0x31) #define CKR_DEVICE_REMOVED (0x32) #define CKR_ENCRYPTED_DATA_INVALID (0x40) #define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41) #define CKR_FUNCTION_CANCELED (0x50) #define CKR_FUNCTION_NOT_PARALLEL (0x51) #define CKR_FUNCTION_NOT_SUPPORTED (0x54) #define CKR_KEY_HANDLE_INVALID (0x60) #define CKR_KEY_SIZE_RANGE (0x62) #define CKR_KEY_TYPE_INCONSISTENT (0x63) #define CKR_KEY_NOT_NEEDED (0x64) #define CKR_KEY_CHANGED (0x65) #define CKR_KEY_NEEDED (0x66) #define CKR_KEY_INDIGESTIBLE (0x67) #define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68) #define CKR_KEY_NOT_WRAPPABLE (0x69) #define CKR_KEY_UNEXTRACTABLE (0x6a) #define CKR_MECHANISM_INVALID (0x70) #define CKR_MECHANISM_PARAM_INVALID (0x71) #define CKR_OBJECT_HANDLE_INVALID (0x82) #define CKR_OPERATION_ACTIVE (0x90) #define CKR_OPERATION_NOT_INITIALIZED (0x91) #define CKR_PIN_INCORRECT (0xa0) #define CKR_PIN_INVALID (0xa1) #define CKR_PIN_LEN_RANGE (0xa2) #define CKR_PIN_EXPIRED (0xa3) #define CKR_PIN_LOCKED (0xa4) #define CKR_SESSION_CLOSED (0xb0) #define CKR_SESSION_COUNT (0xb1) #define CKR_SESSION_HANDLE_INVALID (0xb3) #define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4) #define CKR_SESSION_READ_ONLY (0xb5) #define CKR_SESSION_EXISTS (0xb6) #define CKR_SESSION_READ_ONLY_EXISTS (0xb7) #define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8) #define CKR_SIGNATURE_INVALID (0xc0) #define CKR_SIGNATURE_LEN_RANGE (0xc1) #define CKR_TEMPLATE_INCOMPLETE (0xd0) #define CKR_TEMPLATE_INCONSISTENT (0xd1) #define CKR_TOKEN_NOT_PRESENT (0xe0) #define CKR_TOKEN_NOT_RECOGNIZED (0xe1) #define CKR_TOKEN_WRITE_PROTECTED (0xe2) #define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0) #define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1) #define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2) #define CKR_USER_ALREADY_LOGGED_IN (0x100) #define CKR_USER_NOT_LOGGED_IN (0x101) #define CKR_USER_PIN_NOT_INITIALIZED (0x102) #define CKR_USER_TYPE_INVALID (0x103) #define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104) #define CKR_USER_TOO_MANY_TYPES (0x105) #define CKR_WRAPPED_KEY_INVALID (0x110) #define CKR_WRAPPED_KEY_LEN_RANGE (0x112) #define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113) #define CKR_WRAPPING_KEY_SIZE_RANGE (0x114) #define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115) #define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120) #define CKR_RANDOM_NO_RNG (0x121) #define CKR_DOMAIN_PARAMS_INVALID (0x130) #define CKR_BUFFER_TOO_SMALL (0x150) #define CKR_SAVED_STATE_INVALID (0x160) #define CKR_INFORMATION_SENSITIVE (0x170) #define CKR_STATE_UNSAVEABLE (0x180) #define CKR_CRYPTOKI_NOT_INITIALIZED (0x190) #define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191) #define CKR_MUTEX_BAD (0x1a0) #define CKR_MUTEX_NOT_LOCKED (0x1a1) #define CKR_FUNCTION_REJECTED (0x200) #define CKR_VENDOR_DEFINED ((unsigned long) (1 << 31)) /* Compatibility layer. */ #ifdef CRYPTOKI_COMPAT #undef CK_DEFINE_FUNCTION #define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name /* For NULL. */ #include typedef unsigned char CK_BYTE; typedef unsigned char CK_CHAR; typedef unsigned char CK_UTF8CHAR; typedef unsigned char CK_BBOOL; typedef unsigned long int CK_ULONG; typedef long int CK_LONG; typedef CK_BYTE *CK_BYTE_PTR; typedef CK_CHAR *CK_CHAR_PTR; typedef CK_UTF8CHAR *CK_UTF8CHAR_PTR; typedef CK_ULONG *CK_ULONG_PTR; typedef void *CK_VOID_PTR; typedef void **CK_VOID_PTR_PTR; #define CK_FALSE 0 #define CK_TRUE 1 #ifndef CK_DISABLE_TRUE_FALSE #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #endif typedef struct ck_version CK_VERSION; typedef struct ck_version *CK_VERSION_PTR; typedef struct ck_info CK_INFO; typedef struct ck_info *CK_INFO_PTR; typedef ck_slot_id_t *CK_SLOT_ID_PTR; typedef struct ck_slot_info CK_SLOT_INFO; typedef struct ck_slot_info *CK_SLOT_INFO_PTR; typedef struct ck_token_info CK_TOKEN_INFO; typedef struct ck_token_info *CK_TOKEN_INFO_PTR; typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR; typedef struct ck_session_info CK_SESSION_INFO; typedef struct ck_session_info *CK_SESSION_INFO_PTR; typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR; typedef ck_object_class_t *CK_OBJECT_CLASS_PTR; typedef struct ck_attribute CK_ATTRIBUTE; typedef struct ck_attribute *CK_ATTRIBUTE_PTR; typedef struct ck_date CK_DATE; typedef struct ck_date *CK_DATE_PTR; typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; typedef struct ck_mechanism CK_MECHANISM; typedef struct ck_mechanism *CK_MECHANISM_PTR; typedef struct ck_mechanism_info CK_MECHANISM_INFO; typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR; typedef struct ck_function_list CK_FUNCTION_LIST; typedef struct ck_function_list *CK_FUNCTION_LIST_PTR; typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #define NULL_PTR NULL /* Delete the helper macros defined at the top of the file. */ #undef ck_flags_t #undef ck_version #undef ck_info #undef cryptoki_version #undef manufacturer_id #undef library_description #undef library_version #undef ck_notification_t #undef ck_slot_id_t #undef ck_slot_info #undef slot_description #undef hardware_version #undef firmware_version #undef ck_token_info #undef serial_number #undef max_session_count #undef session_count #undef max_rw_session_count #undef rw_session_count #undef max_pin_len #undef min_pin_len #undef total_public_memory #undef free_public_memory #undef total_private_memory #undef free_private_memory #undef utc_time #undef ck_session_handle_t #undef ck_user_type_t #undef ck_state_t #undef ck_session_info #undef slot_id #undef device_error #undef ck_object_handle_t #undef ck_object_class_t #undef ck_hw_feature_type_t #undef ck_key_type_t #undef ck_certificate_type_t #undef ck_attribute_type_t #undef ck_attribute #undef value #undef value_len #undef ck_date #undef ck_mechanism_type_t #undef ck_mechanism #undef parameter #undef parameter_len #undef ck_mechanism_info #undef min_key_size #undef max_key_size #undef ck_rv_t #undef ck_notify_t #undef ck_function_list #undef ck_createmutex_t #undef ck_destroymutex_t #undef ck_lockmutex_t #undef ck_unlockmutex_t #undef ck_c_initialize_args #undef create_mutex #undef destroy_mutex #undef lock_mutex #undef unlock_mutex #undef reserved #endif /* CRYPTOKI_COMPAT */ /* System dependencies. */ #if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) #pragma pack(pop, cryptoki) #endif #if defined(__cplusplus) } #endif #endif /* PKCS11_H */ libp11-libp11-0.3.1/src/versioninfo.rc000066400000000000000000000015021265040137300173460ustar00rootroot00000000000000#include VS_VERSION_INFO VERSIONINFO FILEVERSION 5,3,0,0 PRODUCTVERSION 0,3,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x21L #else FILEFLAGS 0x20L #endif FILEOS 0x40004L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "Provided under the terms of the GNU General Public License (LGPLv2.1+).\0" VALUE "CompanyName", "OpenSC Project\0" VALUE "FileDescription", "PKCS#11 access library\0" VALUE "FileVersion", "5.3.0.0\0" VALUE "InternalName", "libp11\0" VALUE "LegalCopyright", "OpenSC Project\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libp11-2.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libp11\0" VALUE "ProductVersion", "0,3,1,0\0" VALUE "SpecialBuild", "\0" END END END libp11-libp11-0.3.1/src/versioninfo.rc.in000066400000000000000000000021131265040137300177520ustar00rootroot00000000000000#include VS_VERSION_INFO VERSIONINFO FILEVERSION @LIBP11_LT_CURRENT@,@LIBP11_LT_AGE@,@LIBP11_LT_REVISION@,0 PRODUCTVERSION @LIBP11_VERSION_MAJOR@,@LIBP11_VERSION_MINOR@,@LIBP11_VERSION_FIX@,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x21L #else FILEFLAGS 0x20L #endif FILEOS 0x40004L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "Provided under the terms of the GNU General Public License (LGPLv2.1+).\0" VALUE "CompanyName", "OpenSC Project\0" VALUE "FileDescription", "PKCS#11 access library\0" VALUE "FileVersion", "@LIBP11_LT_CURRENT@.@LIBP11_LT_AGE@.@LIBP11_LT_REVISION@.0\0" VALUE "InternalName", "@PACKAGE_NAME@\0" VALUE "LegalCopyright", "OpenSC Project\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "@PACKAGE_NAME@-@LIBP11_LT_OLDEST@.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "@PACKAGE_NAME@\0" VALUE "ProductVersion", "@LIBP11_VERSION_MAJOR@,@LIBP11_VERSION_MINOR@,@LIBP11_VERSION_FIX@,0\0" VALUE "SpecialBuild", "\0" END END END libp11-libp11-0.3.1/tests/000077500000000000000000000000001265040137300150345ustar00rootroot00000000000000libp11-libp11-0.3.1/tests/Makefile.am000066400000000000000000000010511265040137300170650ustar00rootroot00000000000000EXTRA_DIST = cert.der key.der common.sh AM_CFLAGS = $(OPENSSL_CFLAGS) AM_CPPFLAGS = \ -I$(top_srcdir)/ \ -I$(top_srcdir)/src \ -I$(top_builddir)/ AM_LDFLAGS = -no-install LDADD = ../src/libp11.la $(OPENSSL_LIBS) check_PROGRAMS = fork-test dist_check_SCRIPTS = testpkcs11.softhsm testfork.softhsm testlistkeys.softhsm dist_check_DATA = cert.der key.der pubkey.der TESTS = $(dist_check_SCRIPTS) TESTS_ENVIRONMENT = \ LC_ALL="C" \ EXEEXT=$(EXEEXT) \ top_builddir="$(top_builddir)" \ srcdir="$(srcdir)" # vim: set noexpandtab: libp11-libp11-0.3.1/tests/cert.der000066400000000000000000000014451265040137300164710ustar00rootroot000000000000000!0  Uw+0  *H  01 0 UCA-00  150622112855Z99991231235959Z010Userver-10"0  *H 0 7"[ēӝ9ѿ1U,A@ÜUA,ԮȘd.QkgӺ*/! S<~߳>gՀaBhR@PKO&h @&ϣR2?,N櫽TgͣoF(Uۈ2YFFu XjεP/11Y0J=(;âz7q9m@ֹC*@6 w0u0 U00U 0 localhost0U0UF:?F"qd?`Ƕ10U#0h>܃w5)}40  *H  QmRX> |kg2ʀt92@`]<zߒ1=%ѓ,'I B(I?yNVm׉! S1u 'ox~]+C D{#>n*je(H!V)E(jrMrCf_*n<2(id&V)WBobøn\~=`-N҅(Cx?Dlibp11-libp11-0.3.1/tests/common.sh000077500000000000000000000063361265040137300166730ustar00rootroot00000000000000#!/bin/sh # Copyright (C) 2013 Nikos Mavrogiannopoulos # Copyright (C) 2015 Red Hat, Inc. # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 of the License, or (at # your option) any later version. # # GnuTLS is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GnuTLS; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. echo "Current directory: $(pwd)" echo "Source directory: ${srcdir}" echo "Output directory: ${outdir}" mkdir -p $outdir for i in /usr/lib64/pkcs11 /usr/lib/softhsm /usr/local/lib/softhsm /opt/local/lib/softhsm /usr/lib/x86_64-linux-gnu/softhsm /usr/lib /usr/lib64/softhsm;do if test -f "$i/libsofthsm2.so"; then ADDITIONAL_PARAM="$i/libsofthsm2.so" break else if test -f "$i/libsofthsm.so";then ADDITIONAL_PARAM="$i/libsofthsm.so" break fi fi done if (! test -x /usr/bin/pkcs11-tool && ! test -x /usr/local/bin/pkcs11-tool);then exit 77 fi init_card () { PIN="$1" PUK="$2" if test -x "/usr/local/bin/softhsm2-util"; then export SOFTHSM2_CONF="$outdir/softhsm-testpkcs11.config" SOFTHSM_TOOL="/usr/local/bin/softhsm2-util" fi if test -x "/opt/local/bin/softhsm2-util"; then export SOFTHSM2_CONF="$outdir/softhsm-testpkcs11.config" SOFTHSM_TOOL="/opt/local/bin/softhsm2-util" fi if test -x "/usr/bin/softhsm2-util"; then export SOFTHSM2_CONF="$outdir/softhsm-testpkcs11.config" SOFTHSM_TOOL="/usr/bin/softhsm2-util" fi if test -x "/usr/bin/softhsm"; then export SOFTHSM_CONF="$outdir/softhsm-testpkcs11.config" SOFTHSM_TOOL="/usr/bin/softhsm" fi if test -z "${SOFTHSM_TOOL}"; then echo "Could not find softhsm(2) tool" exit 77 fi if test -z "${SOFTHSM_CONF}"; then rm -rf $outdir/softhsm-testpkcs11.db mkdir -p $outdir/softhsm-testpkcs11.db echo "objectstore.backend = file" > "${SOFTHSM2_CONF}" echo "directories.tokendir = $outdir/softhsm-testpkcs11.db" >> "${SOFTHSM2_CONF}" else rm -rf $outdir/softhsm-testpkcs11.db echo "0:$outdir/softhsm-testpkcs11.db" > "${SOFTHSM_CONF}" fi echo -n "* Initializing smart card... " ${SOFTHSM_TOOL} --init-token --slot 0 --label "libp11-test" --so-pin "${PUK}" --pin "${PIN}" >/dev/null if test $? = 0; then echo ok else echo failed exit 1 fi } PIN=1234 PUK=1234 init_card $PIN $PUK # generate key in token pkcs11-tool -p $PIN --module $ADDITIONAL_PARAM -d 00010203 -a server-key -l -w ${srcdir}/key.der -y privkey >/dev/null if test $? != 0;then exit 1; fi pkcs11-tool -p $PIN --module $ADDITIONAL_PARAM -d 00010203 -a server-key -l -w ${srcdir}/pubkey.der -y pubkey >/dev/null if test $? != 0;then exit 1; fi pkcs11-tool -p $PIN --module $ADDITIONAL_PARAM -d 00010203 -a server-key -l -w ${srcdir}/cert.der -y cert >/dev/null if test $? != 0;then exit 1; fi echo "***************" echo "Listing objects" echo "***************" pkcs11-tool -p $PIN --module $ADDITIONAL_PARAM -l -O libp11-libp11-0.3.1/tests/fork-test.c000066400000000000000000000127131265040137300171220ustar00rootroot00000000000000/* libp11 example code: auth.c * * This examply simply connects to your smart card * and does a public key authentication. * * Feel free to copy all of the code as needed. * */ #include #include #include #include #include #include #include #include #include #include #include #define RANDOM_SOURCE "/dev/urandom" #define RANDOM_SIZE 20 #define MAX_SIGSIZE 256 static void do_fork(); static void error_queue(const char *name); int main(int argc, char *argv[]) { PKCS11_CTX *ctx; PKCS11_SLOT *slots, *slot; PKCS11_CERT *certs; PKCS11_KEY *authkey; PKCS11_CERT *authcert; EVP_PKEY *pubkey = NULL; unsigned char *random = NULL, *signature = NULL; char password[20]; int rc = 0, fd; unsigned int nslots, ncerts, siglen; if (argc < 2) { fprintf(stderr, "usage: %s /usr/lib/opensc-pkcs11.so [PIN]\n", argv[0]); return 1; } do_fork(); ctx = PKCS11_CTX_new(); error_queue("PKCS11_CTX_new"); /* load pkcs #11 module */ do_fork(); rc = PKCS11_CTX_load(ctx, argv[1]); error_queue("PKCS11_CTX_load"); if (rc) { fprintf(stderr, "loading pkcs11 engine failed: %s\n", ERR_reason_error_string(ERR_get_error())); rc = 1; goto nolib; } /* get information on all slots */ do_fork(); rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); error_queue("PKCS11_enumerate_slots"); if (rc < 0) { fprintf(stderr, "no slots available\n"); rc = 2; goto noslots; } /* get first slot with a token */ do_fork(); slot = PKCS11_find_token(ctx, slots, nslots); error_queue("PKCS11_find_token"); if (slot == NULL || slot->token == NULL) { fprintf(stderr, "no token available\n"); rc = 3; goto notoken; } printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); if (!slot->token->loginRequired) goto loggedin; /* get password */ if (argc > 2) { strcpy(password, argv[2]); } else { exit(1); } loggedin: /* perform pkcs #11 login */ do_fork(); rc = PKCS11_login(slot, 0, password); error_queue("PKCS11_login"); memset(password, 0, strlen(password)); if (rc != 0) { fprintf(stderr, "PKCS11_login failed\n"); goto failed; } /* get all certs */ do_fork(); rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts); error_queue("PKCS11_enumerate_certs"); if (rc) { fprintf(stderr, "PKCS11_enumerate_certs failed\n"); goto failed; } if (ncerts <= 0) { fprintf(stderr, "no certificates found\n"); goto failed; } /* use the first cert */ authcert=&certs[0]; /* get random bytes */ random = OPENSSL_malloc(RANDOM_SIZE); if (random == NULL) goto failed; fd = open(RANDOM_SOURCE, O_RDONLY); if (fd < 0) { fprintf(stderr, "fatal: cannot open RANDOM_SOURCE: %s\n", strerror(errno)); goto failed; } rc = read(fd, random, RANDOM_SIZE); if (rc < 0) { fprintf(stderr, "fatal: read from random source failed: %s\n", strerror(errno)); close(fd); goto failed; } if (rc < RANDOM_SIZE) { fprintf(stderr, "fatal: read returned less than %d<%d bytes\n", rc, RANDOM_SIZE); close(fd); goto failed; } close(fd); do_fork(); authkey = PKCS11_find_key(authcert); error_queue("PKCS11_find_key"); if (authkey == NULL) { fprintf(stderr, "no key matching certificate available\n"); goto failed; } /* ask for a sha1 hash of the random data, signed by the key */ siglen = MAX_SIGSIZE; signature = OPENSSL_malloc(MAX_SIGSIZE); if (signature == NULL) goto failed; /* do the operations in child */ do_fork(); rc = PKCS11_sign(NID_sha1, random, RANDOM_SIZE, signature, &siglen, authkey); error_queue("PKCS11_sign"); if (rc != 1) { fprintf(stderr, "fatal: pkcs11_sign failed\n"); goto failed; } /* verify the signature */ pubkey = X509_get_pubkey(authcert->x509); if (pubkey == NULL) { fprintf(stderr, "could not extract public key\n"); goto failed; } /* now verify the result */ rc = RSA_verify(NID_sha1, random, RANDOM_SIZE, signature, siglen, pubkey->pkey.rsa); if (rc != 1) { fprintf(stderr, "fatal: RSA_verify failed\n"); goto failed; } if (pubkey != NULL) EVP_PKEY_free(pubkey); if (random != NULL) OPENSSL_free(random); if (signature != NULL) OPENSSL_free(signature); PKCS11_release_all_slots(ctx, slots, nslots); PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); printf("authentication successfull.\n"); return 0; failed: notoken: PKCS11_release_all_slots(ctx, slots, nslots); noslots: PKCS11_CTX_unload(ctx); nolib: PKCS11_CTX_free(ctx); printf("authentication failed.\n"); return 1; } static void do_fork() { int status = 0; pid_t pid = fork(); switch (pid) { case -1: /* failed */ perror("fork"); exit(5); case 0: /* child */ return; default: /* parent */ waitpid(pid, &status, 0); if (WIFEXITED(status)) exit(WEXITSTATUS(status)); if (WIFSIGNALED(status)) fprintf(stderr, "Child terminated by signal #%d\n", WTERMSIG(status)); else perror("waitpid"); exit(2); } } static void error_queue(const char *name) { if (ERR_peek_last_error()) { fprintf(stderr, "%s generated errors:\n", name); ERR_print_errors_fp(stderr); } } /* vim: set noexpandtab: */ libp11-libp11-0.3.1/tests/key.der000066400000000000000000000022471265040137300163250ustar00rootroot0000000000000007"[ēӝ9ѿ1U,A@ÜUA,ԮȘd.QkgӺ*/! S<~߳>gՀaBhR@PKO&h @&ϣR2?,N櫽TgͣoF(Uۈ2YFFu XjεP/11Y0J=(;âz7q9m@ֹC*@6 ApmTizL1Y9<I~I<+&-r;6P҄w36%nT>cYC[rƄg+k 8J"GJvz|i!!7N]NrK}z.jwX:`H%=xjIk b3؎TD8}4')״eNL֋de*;~9]v=  ,:/6?Z?0 c(Nx-PMLn(KviIK}جTm]lRJ}ReI׏&tO`U7G]Eob]9W u2H~T ߨ҇z{mNݺJWsXO&훺=ᐟ 8.Y^zSYUJ% 4|Кd;=@t̿N!NxmD*l]YŠ;^rx:EZ <SA1j5ҳo]ei: N"W[=yL&_HOUי.y ]^WpvދM)K__*Ohuik L5_F@~o+R0rgN4{h+UY1ccV%'gU['Ǘ4m eE׾B:^Mf0WFlibp11-libp11-0.3.1/tests/pubkey.der000066400000000000000000000004461265040137300170330ustar00rootroot000000000000000"0  *H 0 7"[ēӝ9ѿ1U,A@ÜUA,ԮȘd.QkgӺ*/! S<~߳>gՀaBhR@PKO&h @&ϣR2?,N櫽TgͣoF(Uۈ2YFFu XjεP/11Y0J=(;âz7q9m@ֹC*@6 libp11-libp11-0.3.1/tests/testfork.softhsm000077500000000000000000000016241265040137300203100ustar00rootroot00000000000000#!/bin/sh # Copyright (C) 2013 Nikos Mavrogiannopoulos # Copyright (C) 2015 Red Hat, Inc. # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 of the License, or (at # your option) any later version. # # GnuTLS is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GnuTLS; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. outdir="output.$$" . ${srcdir}/common.sh ./fork-test $ADDITIONAL_PARAM $PIN if test $? != 0;then exit 1; fi rm -rf "$outdir" exit 0 libp11-libp11-0.3.1/tests/testlistkeys.softhsm000077500000000000000000000016351265040137300212200ustar00rootroot00000000000000#!/bin/sh # Copyright (C) 2013 Nikos Mavrogiannopoulos # Copyright (C) 2015 Red Hat, Inc. # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 of the License, or (at # your option) any later version. # # GnuTLS is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GnuTLS; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. outdir="output.$$" . ${srcdir}/common.sh ../examples/listkeys $ADDITIONAL_PARAM $PIN if test $? != 0;then exit 1; fi rm -rf "$outdir" exit 0 libp11-libp11-0.3.1/tests/testpkcs11.softhsm000077500000000000000000000020671265040137300204530ustar00rootroot00000000000000#!/bin/sh # Copyright (C) 2013 Nikos Mavrogiannopoulos # # This file is part of GnuTLS. # # GnuTLS is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 of the License, or (at # your option) any later version. # # GnuTLS is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GnuTLS; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. outdir="output.$$" . ${srcdir}/common.sh ../examples/auth $ADDITIONAL_PARAM $PIN if test $? != 0;then echo "Basic PKCS #11 test test failed" exit 1; fi ../examples/rawrsasign $ADDITIONAL_PARAM $PIN if test $? != 0;then echo "Raw RSA signature test failed" exit 1; fi rm -rf "$outdir" exit 0