summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSajesh Kumar Saran2013-01-04 18:02:27 -0600
committerSajesh Kumar Saran2013-01-04 18:02:38 -0600
commitfbdeb6d2cf3ccd8b79d3e1bfe0d82d79746154e6 (patch)
tree32e39437f00a5915b74bb3fc8a4e653a8974eaeb
parent1d86b9c1feda612f366554a2d67786f105cd67ba (diff)
downloadlibp11-fbdeb6d2cf3ccd8b79d3e1bfe0d82d79746154e6.tar.gz
libp11-fbdeb6d2cf3ccd8b79d3e1bfe0d82d79746154e6.tar.xz
libp11-fbdeb6d2cf3ccd8b79d3e1bfe0d82d79746154e6.zip
libp11 initial commit
-rw-r--r--COPYING510
-rw-r--r--Makefile.am26
-rw-r--r--Makefile.mak13
-rw-r--r--NEWS39
-rw-r--r--README.txt1
-rwxr-xr-xbootstrap10
-rw-r--r--configure.ac281
-rw-r--r--doc/Makefile.am26
-rw-r--r--doc/README10
-rw-r--r--doc/doxygen.conf.in1310
-rw-r--r--doc/nonpersistent/Makefile.am59
-rwxr-xr-xdoc/nonpersistent/export-wiki.sh71
-rw-r--r--doc/nonpersistent/export-wiki.xsl58
-rwxr-xr-xdoc/nonpersistent/svn2cl.xsl295
-rw-r--r--examples/README25
-rw-r--r--examples/auth.c225
-rw-r--r--examples/decrypt.c240
-rw-r--r--examples/getrandom.c88
-rw-r--r--packaged1
-rw-r--r--src/Makefile.am42
-rw-r--r--src/Makefile.mak33
-rw-r--r--src/libp11-int.h159
-rw-r--r--src/libp11.exports37
-rw-r--r--src/libp11.h428
-rw-r--r--src/libp11.pc.in12
-rw-r--r--src/libpkcs11.c101
-rw-r--r--src/p11_attr.c156
-rw-r--r--src/p11_cert.c258
-rw-r--r--src/p11_err.c160
-rw-r--r--src/p11_key.c470
-rw-r--r--src/p11_load.c125
-rw-r--r--src/p11_misc.c63
-rw-r--r--src/p11_ops.c191
-rw-r--r--src/p11_rsa.c158
-rw-r--r--src/p11_slot.c416
-rw-r--r--src/pkcs11.h1357
-rw-r--r--src/versioninfo.rc.in35
-rw-r--r--winconfig.h1
38 files changed, 7489 insertions, 1 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..b124cf5
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,510 @@
1
2 GNU LESSER GENERAL PUBLIC LICENSE
3 Version 2.1, February 1999
4
5 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
6 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7 Everyone is permitted to copy and distribute verbatim copies
8 of this license document, but changing it is not allowed.
9
10[This is the first released version of the Lesser GPL. It also counts
11 as the successor of the GNU Library Public License, version 2, hence
12 the version number 2.1.]
13
14 Preamble
15
16 The licenses for most software are designed to take away your
17freedom to share and change it. By contrast, the GNU General Public
18Licenses are intended to guarantee your freedom to share and change
19free software--to make sure the software is free for all its users.
20
21 This license, the Lesser General Public License, applies to some
22specially designated software packages--typically libraries--of the
23Free Software Foundation and other authors who decide to use it. You
24can use it too, but we suggest you first think carefully about whether
25this license or the ordinary General Public License is the better
26strategy to use in any particular case, based on the explanations
27below.
28
29 When we speak of free software, we are referring to freedom of use,
30not price. Our General Public Licenses are designed to make sure that
31you have the freedom to distribute copies of free software (and charge
32for this service if you wish); that you receive source code or can get
33it if you want it; that you can change the software and use pieces of
34it in new free programs; and that you are informed that you can do
35these things.
36
37 To protect your rights, we need to make restrictions that forbid
38distributors to deny you these rights or to ask you to surrender these
39rights. These restrictions translate to certain responsibilities for
40you if you distribute copies of the library or if you modify it.
41
42 For example, if you distribute copies of the library, whether gratis
43or for a fee, you must give the recipients all the rights that we gave
44you. You must make sure that they, too, receive or can get the source
45code. If you link other code with the library, you must provide
46complete object files to the recipients, so that they can relink them
47with the library after making changes to the library and recompiling
48it. And you must show them these terms so they know their rights.
49
50 We protect your rights with a two-step method: (1) we copyright the
51library, and (2) we offer you this license, which gives you legal
52permission to copy, distribute and/or modify the library.
53
54 To protect each distributor, we want to make it very clear that
55there is no warranty for the free library. Also, if the library is
56modified by someone else and passed on, the recipients should know
57that what they have is not the original version, so that the original
58author's reputation will not be affected by problems that might be
59introduced by others.
60
61 Finally, software patents pose a constant threat to the existence of
62any free program. We wish to make sure that a company cannot
63effectively restrict the users of a free program by obtaining a
64restrictive license from a patent holder. Therefore, we insist that
65any patent license obtained for a version of the library must be
66consistent with the full freedom of use specified in this license.
67
68 Most GNU software, including some libraries, is covered by the
69ordinary GNU General Public License. This license, the GNU Lesser
70General Public License, applies to certain designated libraries, and
71is quite different from the ordinary General Public License. We use
72this license for certain libraries in order to permit linking those
73libraries into non-free programs.
74
75 When a program is linked with a library, whether statically or using
76a shared library, the combination of the two is legally speaking a
77combined work, a derivative of the original library. The ordinary
78General Public License therefore permits such linking only if the
79entire combination fits its criteria of freedom. The Lesser General
80Public License permits more lax criteria for linking other code with
81the library.
82
83 We call this license the "Lesser" General Public License because it
84does Less to protect the user's freedom than the ordinary General
85Public License. It also provides other free software developers Less
86of an advantage over competing non-free programs. These disadvantages
87are the reason we use the ordinary General Public License for many
88libraries. However, the Lesser license provides advantages in certain
89special circumstances.
90
91 For example, on rare occasions, there may be a special need to
92encourage the widest possible use of a certain library, so that it
93becomes a de-facto standard. To achieve this, non-free programs must
94be allowed to use the library. A more frequent case is that a free
95library does the same job as widely used non-free libraries. In this
96case, there is little to gain by limiting the free library to free
97software only, so we use the Lesser General Public License.
98
99 In other cases, permission to use a particular library in non-free
100programs enables a greater number of people to use a large body of
101free software. For example, permission to use the GNU C Library in
102non-free programs enables many more people to use the whole GNU
103operating system, as well as its variant, the GNU/Linux operating
104system.
105
106 Although the Lesser General Public License is Less protective of the
107users' freedom, it does ensure that the user of a program that is
108linked with the Library has the freedom and the wherewithal to run
109that program using a modified version of the Library.
110
111 The precise terms and conditions for copying, distribution and
112modification follow. Pay close attention to the difference between a
113"work based on the library" and a "work that uses the library". The
114former contains code derived from the library, whereas the latter must
115be combined with the library in order to run.
116
117 GNU LESSER GENERAL PUBLIC LICENSE
118 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
119
120 0. This License Agreement applies to any software library or other
121program which contains a notice placed by the copyright holder or
122other authorized party saying it may be distributed under the terms of
123this Lesser General Public License (also called "this License").
124Each licensee is addressed as "you".
125
126 A "library" means a collection of software functions and/or data
127prepared so as to be conveniently linked with application programs
128(which use some of those functions and data) to form executables.
129
130 The "Library", below, refers to any such software library or work
131which has been distributed under these terms. A "work based on the
132Library" means either the Library or any derivative work under
133copyright law: that is to say, a work containing the Library or a
134portion of it, either verbatim or with modifications and/or translated
135straightforwardly into another language. (Hereinafter, translation is
136included without limitation in the term "modification".)
137
138 "Source code" for a work means the preferred form of the work for
139making modifications to it. For a library, complete source code means
140all the source code for all modules it contains, plus any associated
141interface definition files, plus the scripts used to control
142compilation and installation of the library.
143
144 Activities other than copying, distribution and modification are not
145covered by this License; they are outside its scope. The act of
146running a program using the Library is not restricted, and output from
147such a program is covered only if its contents constitute a work based
148on the Library (independent of the use of the Library in a tool for
149writing it). Whether that is true depends on what the Library does
150and what the program that uses the Library does.
151
152 1. You may copy and distribute verbatim copies of the Library's
153complete source code as you receive it, in any medium, provided that
154you conspicuously and appropriately publish on each copy an
155appropriate copyright notice and disclaimer of warranty; keep intact
156all the notices that refer to this License and to the absence of any
157warranty; and distribute a copy of this License along with the
158Library.
159
160 You may charge a fee for the physical act of transferring a copy,
161and you may at your option offer warranty protection in exchange for a
162fee.
163
164 2. You may modify your copy or copies of the Library or any portion
165of it, thus forming a work based on the Library, and copy and
166distribute such modifications or work under the terms of Section 1
167above, provided that you also meet all of these conditions:
168
169 a) The modified work must itself be a software library.
170
171 b) You must cause the files modified to carry prominent notices
172 stating that you changed the files and the date of any change.
173
174 c) You must cause the whole of the work to be licensed at no
175 charge to all third parties under the terms of this License.
176
177 d) If a facility in the modified Library refers to a function or a
178 table of data to be supplied by an application program that uses
179 the facility, other than as an argument passed when the facility
180 is invoked, then you must make a good faith effort to ensure that,
181 in the event an application does not supply such function or
182 table, the facility still operates, and performs whatever part of
183 its purpose remains meaningful.
184
185 (For example, a function in a library to compute square roots has
186 a purpose that is entirely well-defined independent of the
187 application. Therefore, Subsection 2d requires that any
188 application-supplied function or table used by this function must
189 be optional: if the application does not supply it, the square
190 root function must still compute square roots.)
191
192These requirements apply to the modified work as a whole. If
193identifiable sections of that work are not derived from the Library,
194and can be reasonably considered independent and separate works in
195themselves, then this License, and its terms, do not apply to those
196sections when you distribute them as separate works. But when you
197distribute the same sections as part of a whole which is a work based
198on the Library, the distribution of the whole must be on the terms of
199this License, whose permissions for other licensees extend to the
200entire whole, and thus to each and every part regardless of who wrote
201it.
202
203Thus, it is not the intent of this section to claim rights or contest
204your rights to work written entirely by you; rather, the intent is to
205exercise the right to control the distribution of derivative or
206collective works based on the Library.
207
208In addition, mere aggregation of another work not based on the Library
209with the Library (or with a work based on the Library) on a volume of
210a storage or distribution medium does not bring the other work under
211the scope of this License.
212
213 3. You may opt to apply the terms of the ordinary GNU General Public
214License instead of this License to a given copy of the Library. To do
215this, you must alter all the notices that refer to this License, so
216that they refer to the ordinary GNU General Public License, version 2,
217instead of to this License. (If a newer version than version 2 of the
218ordinary GNU General Public License has appeared, then you can specify
219that version instead if you wish.) Do not make any other change in
220these notices.
221
222 Once this change is made in a given copy, it is irreversible for
223that copy, so the ordinary GNU General Public License applies to all
224subsequent copies and derivative works made from that copy.
225
226 This option is useful when you wish to copy part of the code of
227the Library into a program that is not a library.
228
229 4. You may copy and distribute the Library (or a portion or
230derivative of it, under Section 2) in object code or executable form
231under the terms of Sections 1 and 2 above provided that you accompany
232it with the complete corresponding machine-readable source code, which
233must be distributed under the terms of Sections 1 and 2 above on a
234medium customarily used for software interchange.
235
236 If distribution of object code is made by offering access to copy
237from a designated place, then offering equivalent access to copy the
238source code from the same place satisfies the requirement to
239distribute the source code, even though third parties are not
240compelled to copy the source along with the object code.
241
242 5. A program that contains no derivative of any portion of the
243Library, but is designed to work with the Library by being compiled or
244linked with it, is called a "work that uses the Library". Such a
245work, in isolation, is not a derivative work of the Library, and
246therefore falls outside the scope of this License.
247
248 However, linking a "work that uses the Library" with the Library
249creates an executable that is a derivative of the Library (because it
250contains portions of the Library), rather than a "work that uses the
251library". The executable is therefore covered by this License.
252Section 6 states terms for distribution of such executables.
253
254 When a "work that uses the Library" uses material from a header file
255that is part of the Library, the object code for the work may be a
256derivative work of the Library even though the source code is not.
257Whether this is true is especially significant if the work can be
258linked without the Library, or if the work is itself a library. The
259threshold for this to be true is not precisely defined by law.
260
261 If such an object file uses only numerical parameters, data
262structure layouts and accessors, and small macros and small inline
263functions (ten lines or less in length), then the use of the object
264file is unrestricted, regardless of whether it is legally a derivative
265work. (Executables containing this object code plus portions of the
266Library will still fall under Section 6.)
267
268 Otherwise, if the work is a derivative of the Library, you may
269distribute the object code for the work under the terms of Section 6.
270Any executables containing that work also fall under Section 6,
271whether or not they are linked directly with the Library itself.
272
273 6. As an exception to the Sections above, you may also combine or
274link a "work that uses the Library" with the Library to produce a
275work containing portions of the Library, and distribute that work
276under terms of your choice, provided that the terms permit
277modification of the work for the customer's own use and reverse
278engineering for debugging such modifications.
279
280 You must give prominent notice with each copy of the work that the
281Library is used in it and that the Library and its use are covered by
282this License. You must supply a copy of this License. If the work
283during execution displays copyright notices, you must include the
284copyright notice for the Library among them, as well as a reference
285directing the user to the copy of this License. Also, you must do one
286of these things:
287
288 a) Accompany the work with the complete corresponding
289 machine-readable source code for the Library including whatever
290 changes were used in the work (which must be distributed under
291 Sections 1 and 2 above); and, if the work is an executable linked
292 with the Library, with the complete machine-readable "work that
293 uses the Library", as object code and/or source code, so that the
294 user can modify the Library and then relink to produce a modified
295 executable containing the modified Library. (It is understood
296 that the user who changes the contents of definitions files in the
297 Library will not necessarily be able to recompile the application
298 to use the modified definitions.)
299
300 b) Use a suitable shared library mechanism for linking with the
301 Library. A suitable mechanism is one that (1) uses at run time a
302 copy of the library already present on the user's computer system,
303 rather than copying library functions into the executable, and (2)
304 will operate properly with a modified version of the library, if
305 the user installs one, as long as the modified version is
306 interface-compatible with the version that the work was made with.
307
308 c) Accompany the work with a written offer, valid for at least
309 three years, to give the same user the materials specified in
310 Subsection 6a, above, for a charge no more than the cost of
311 performing this distribution.
312
313 d) If distribution of the work is made by offering access to copy
314 from a designated place, offer equivalent access to copy the above
315 specified materials from the same place.
316
317 e) Verify that the user has already received a copy of these
318 materials or that you have already sent this user a copy.
319
320 For an executable, the required form of the "work that uses the
321Library" must include any data and utility programs needed for
322reproducing the executable from it. However, as a special exception,
323the materials to be distributed need not include anything that is
324normally distributed (in either source or binary form) with the major
325components (compiler, kernel, and so on) of the operating system on
326which the executable runs, unless that component itself accompanies
327the executable.
328
329 It may happen that this requirement contradicts the license
330restrictions of other proprietary libraries that do not normally
331accompany the operating system. Such a contradiction means you cannot
332use both them and the Library together in an executable that you
333distribute.
334
335 7. You may place library facilities that are a work based on the
336Library side-by-side in a single library together with other library
337facilities not covered by this License, and distribute such a combined
338library, provided that the separate distribution of the work based on
339the Library and of the other library facilities is otherwise
340permitted, and provided that you do these two things:
341
342 a) Accompany the combined library with a copy of the same work
343 based on the Library, uncombined with any other library
344 facilities. This must be distributed under the terms of the
345 Sections above.
346
347 b) Give prominent notice with the combined library of the fact
348 that part of it is a work based on the Library, and explaining
349 where to find the accompanying uncombined form of the same work.
350
351 8. You may not copy, modify, sublicense, link with, or distribute
352the Library except as expressly provided under this License. Any
353attempt otherwise to copy, modify, sublicense, link with, or
354distribute the Library is void, and will automatically terminate your
355rights under this License. However, parties who have received copies,
356or rights, from you under this License will not have their licenses
357terminated so long as such parties remain in full compliance.
358
359 9. You are not required to accept this License, since you have not
360signed it. However, nothing else grants you permission to modify or
361distribute the Library or its derivative works. These actions are
362prohibited by law if you do not accept this License. Therefore, by
363modifying or distributing the Library (or any work based on the
364Library), you indicate your acceptance of this License to do so, and
365all its terms and conditions for copying, distributing or modifying
366the Library or works based on it.
367
368 10. Each time you redistribute the Library (or any work based on the
369Library), the recipient automatically receives a license from the
370original licensor to copy, distribute, link with or modify the Library
371subject to these terms and conditions. You may not impose any further
372restrictions on the recipients' exercise of the rights granted herein.
373You are not responsible for enforcing compliance by third parties with
374this License.
375
376 11. If, as a consequence of a court judgment or allegation of patent
377infringement or for any other reason (not limited to patent issues),
378conditions are imposed on you (whether by court order, agreement or
379otherwise) that contradict the conditions of this License, they do not
380excuse you from the conditions of this License. If you cannot
381distribute so as to satisfy simultaneously your obligations under this
382License and any other pertinent obligations, then as a consequence you
383may not distribute the Library at all. For example, if a patent
384license would not permit royalty-free redistribution of the Library by
385all those who receive copies directly or indirectly through you, then
386the only way you could satisfy both it and this License would be to
387refrain entirely from distribution of the Library.
388
389If any portion of this section is held invalid or unenforceable under
390any particular circumstance, the balance of the section is intended to
391apply, and the section as a whole is intended to apply in other
392circumstances.
393
394It is not the purpose of this section to induce you to infringe any
395patents or other property right claims or to contest validity of any
396such claims; this section has the sole purpose of protecting the
397integrity of the free software distribution system which is
398implemented by public license practices. Many people have made
399generous contributions to the wide range of software distributed
400through that system in reliance on consistent application of that
401system; it is up to the author/donor to decide if he or she is willing
402to distribute software through any other system and a licensee cannot
403impose that choice.
404
405This section is intended to make thoroughly clear what is believed to
406be a consequence of the rest of this License.
407
408 12. If the distribution and/or use of the Library is restricted in
409certain countries either by patents or by copyrighted interfaces, the
410original copyright holder who places the Library under this License
411may add an explicit geographical distribution limitation excluding those
412countries, so that distribution is permitted only in or among
413countries not thus excluded. In such case, this License incorporates
414the limitation as if written in the body of this License.
415
416 13. The Free Software Foundation may publish revised and/or new
417versions of the Lesser General Public License from time to time.
418Such new versions will be similar in spirit to the present version,
419but may differ in detail to address new problems or concerns.
420
421Each version is given a distinguishing version number. If the Library
422specifies a version number of this License which applies to it and
423"any later version", you have the option of following the terms and
424conditions either of that version or of any later version published by
425the Free Software Foundation. If the Library does not specify a
426license version number, you may choose any version ever published by
427the Free Software Foundation.
428
429 14. If you wish to incorporate parts of the Library into other free
430programs whose distribution conditions are incompatible with these,
431write to the author to ask for permission. For software which is
432copyrighted by the Free Software Foundation, write to the Free
433Software Foundation; we sometimes make exceptions for this. Our
434decision will be guided by the two goals of preserving the free status
435of all derivatives of our free software and of promoting the sharing
436and reuse of software generally.
437
438 NO WARRANTY
439
440 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
441WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
442EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
443OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
444KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
445IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
446PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
447LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
448THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
449
450 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
451WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
452AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
453FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
454CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
455LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
456RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
457FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
458SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
459DAMAGES.
460
461 END OF TERMS AND CONDITIONS
462
463 How to Apply These Terms to Your New Libraries
464
465 If you develop a new library, and you want it to be of the greatest
466possible use to the public, we recommend making it free software that
467everyone can redistribute and change. You can do so by permitting
468redistribution under these terms (or, alternatively, under the terms
469of the ordinary General Public License).
470
471 To apply these terms, attach the following notices to the library.
472It is safest to attach them to the start of each source file to most
473effectively convey the exclusion of warranty; and each file should
474have at least the "copyright" line and a pointer to where the full
475notice is found.
476
477
478 <one line to give the library's name and a brief idea of what it does.>
479 Copyright (C) <year> <name of author>
480
481 This library is free software; you can redistribute it and/or
482 modify it under the terms of the GNU Lesser General Public
483 License as published by the Free Software Foundation; either
484 version 2.1 of the License, or (at your option) any later version.
485
486 This library is distributed in the hope that it will be useful,
487 but WITHOUT ANY WARRANTY; without even the implied warranty of
488 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
489 Lesser General Public License for more details.
490
491 You should have received a copy of the GNU Lesser General Public
492 License along with this library; if not, write to the Free Software
493 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
494
495Also add information on how to contact you by electronic and paper mail.
496
497You should also get your employer (if you work as a programmer) or
498your school, if any, to sign a "copyright disclaimer" for the library,
499if necessary. Here is a sample; alter the names:
500
501 Yoyodyne, Inc., hereby disclaims all copyright interest in the
502 library `Frob' (a library for tweaking knobs) written by James
503 Random Hacker.
504
505 <signature of Ty Coon>, 1 April 1990
506 Ty Coon, President of Vice
507
508That's all there is to it!
509
510
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..2287cf7
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,26 @@
1AUTOMAKE_OPTIONS = foreign 1.10
2ACLOCAL_AMFLAGS = -I m4
3
4MAINTAINERCLEANFILES = \
5 config.log config.status \
6 $(srcdir)/Makefile.in \
7 $(srcdir)/config.h.in $(srcdir)/config.h.in~ $(srcdir)/configure \
8 $(srcdir)/install-sh $(srcdir)/ltmain.sh $(srcdir)/missing \
9 $(srcdir)/depcomp $(srcdir)/aclocal.m4 \
10 $(srcdir)/config.guess $(srcdir)/config.sub \
11 $(srcdir)/m4/ltsugar.m4 $(srcdir)/m4/libtool.m4 \
12 $(srcdir)/m4/ltversion.m4 $(srcdir)/m4/lt~obsolete.m4 \
13 $(srcdir)/m4/ltoptions.m4 \
14 $(srcdir)/packaged
15EXTRA_DIST = svnignore Makefile.mak winconfig.h
16
17dist_noinst_DATA = COPYING bootstrap \
18 $(srcdir)/examples/Makefile $(srcdir)/examples/*.c $(srcdir)/examples/README
19dist_doc_DATA = NEWS
20
21SUBDIRS = src doc
22
23# Allow detection of packaged tarball
24dist-hook:
25 $(MKDIR_P) "$(distdir)/m4"
26 echo > "$(distdir)/packaged"
diff --git a/Makefile.mak b/Makefile.mak
new file mode 100644
index 0000000..bfb1a31
--- /dev/null
+++ b/Makefile.mak
@@ -0,0 +1,13 @@
1
2SUBDIRS = src
3
4all::
5
6all:: config.h
7
8config.h: winconfig.h
9 @copy /y winconfig.h config.h
10
11all depend install clean::
12 @for %i in ( $(SUBDIRS) ) do \
13 @cmd /c "cd %i && $(MAKE) /nologo /f Makefile.mak $@"
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..801871d
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,39 @@
1NEWS for Libp11 -- History of user visible changes
2
3New in 0.2.8; 2011-04-15; Martin Paljak
4* Bumped soname for PKCS11_token struct size changes (Martin Paljak).
5* Display the number of available slots (Ludovic Rousseau).
6* Add openssl libcrypto to pkg-config private libs list (Kalev Lember).
7* Fix building examples with --no-add-needed which is the default in Fedora
8 (Kalev Lember).
9* Expose more token flags in PKCS11_token structure (Kalev Lember).
10* Check that private data is not NULL in pkcs11_release_slot (Robin Bryce,
11 ticket #137).
12
13New in 0.2.7; 2009-10-20; Andreas Jellinghaus
14* If CKR_CRYPTOKI_ALREADY_INITIALIZED is returned from C_Initialize(): ignore.
15 (Needed for unloaded/reloaded engines e.g. in wpa_supplicant.) By David Smith.
16
17New in 0.2.6; 2009-07-22; Andreas Jellinghaus
18* Fix new version: add new symbol to export file
19* fix building on MSVC plattform
20
21New in 0.2.5; 2009-06-15; Andreas Jellinghaus
22* Add function to export the slot id (Douglas E. Engert).
23* Increase library version because of the new function.
24
25New in 0.2.4; 2008-07-31; Andreas Jellinghaus
26* Build system rewritten (NOTICE: configure options was modified).
27 The build system can produce outputs for *NIX, cygwin and native
28 windows (using mingw).
29* added PKCS11_CTX_init_args (David Smith).
30* fix segfault in init_args code.
31* implemented PKCS11_private_encrypt (with PKCS11_sign now based on it)
32 (Arnaud Ebalard)
33
34New in 0.2.3; 2007-07-11; Andreas Jellinghaus
35* update wiki export script (add images, fix links).
36* replaced rsa header files from rsalabs (official) with scute (open source).
37* allow CKR_USER_ALREADY_LOGGED_IN on C_Login.
38* mark internal functions as static.
39* add code to store public keys and generate keys.
diff --git a/README.txt b/README.txt
deleted file mode 100644
index b35787d..0000000
--- a/README.txt
+++ /dev/null
@@ -1 +0,0 @@
1Initial temporary file
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..1ed89d2
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,10 @@
1#!/bin/sh
2
3set -e
4set -x
5if test -f Makefile; then
6 make distclean
7fi
8rm -rf *~ *.cache *.m4 config.guess config.log \
9 config.status config.sub depcomp ltmain.sh
10autoreconf --verbose --install --force
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..336542a
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,281 @@
1dnl -*- mode: m4; -*-
2
3AC_PREREQ(2.60)
4
5define([PACKAGE_VERSION_MAJOR], [0])
6define([PACKAGE_VERSION_MINOR], [2])
7define([PACKAGE_VERSION_FIX], [9])
8define([PACKAGE_SUFFIX], [-svn-r201])
9
10AC_INIT([libp11],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX])
11AC_CONFIG_AUX_DIR([.])
12AC_CONFIG_HEADERS([config.h])
13AC_CONFIG_MACRO_DIR([m4])
14AM_INIT_AUTOMAKE([${PACKAGE_NAME}], [${PACKAGE_VERSION}])
15
16LIBP11_VERSION_MAJOR="PACKAGE_VERSION_MAJOR"
17LIBP11_VERSION_MINOR="PACKAGE_VERSION_MINOR"
18LIBP11_VERSION_FIX="PACKAGE_VERSION_FIX"
19
20# LT Version numbers, remember to change them just *before* a release.
21# (Code changed: REVISION++)
22# (Oldest interface removed: OLDEST++)
23# (Interfaces added: CURRENT++, REVISION=0)
24LIBP11_LT_CURRENT="4"
25LIBP11_LT_OLDEST="2"
26LIBP11_LT_REVISION="0"
27LIBP11_LT_AGE="$((${LIBP11_LT_CURRENT}-${LIBP11_LT_OLDEST}))"
28
29AC_CONFIG_SRCDIR([src/libp11.h])
30
31AC_CANONICAL_HOST
32AC_PROG_CC
33PKG_PROG_PKG_CONFIG
34AC_C_BIGENDIAN
35
36AC_MSG_CHECKING([svn checkout])
37if test -e "${srcdir}/packaged"; then
38 svn_checkout="no"
39else
40 svn_checkout="yes"
41fi
42AC_MSG_RESULT([${svn_checkout}])
43
44AC_ARG_WITH(
45 [cygwin-native],
46 [AS_HELP_STRING([--with-cygwin-native],[compile native win32])],
47 ,
48 [with_cygwin_native="no"]
49)
50
51dnl Check for some target-specific stuff
52test -z "${WIN32}" && WIN32="no"
53test -z "${CYGWIN}" && CYGWIN="no"
54case "${host}" in
55 *-mingw*|*-winnt*)
56 WIN32="yes"
57 CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN"
58 WIN_LIBPREFIX="lib"
59 ;;
60 *-cygwin*)
61 AC_MSG_CHECKING([cygwin mode to use])
62 CYGWIN="yes"
63 if test "${with_cygwin_native}" = "yes"; then
64 AC_MSG_RESULT([Using native win32])
65 CPPFLAGS="${CPPFLAGS} -DWIN32_LEAN_AND_MEAN"
66 CFLAGS="${CFLAGS} -mno-cygwin"
67 WIN32="yes"
68 else
69 AC_MSG_RESULT([Using cygwin])
70 CPPFLAGS="${CPPFLAGS} -DCRYPTOKI_FORCE_WIN32"
71 WIN_LIBPREFIX="cyg"
72 AC_DEFINE([USE_CYGWIN], [1], [Define if you are on Cygwin])
73 fi
74 ;;
75esac
76
77AC_ARG_ENABLE(
78 [strict],
79 [AS_HELP_STRING([--enable-strict],[enable strict compile mode @<:@disabled@:>@])],
80 ,
81 [enable_strict="no"]
82)
83
84AC_ARG_ENABLE(
85 [pedantic],
86 [AS_HELP_STRING([--enable-pedantic],[enable pedantic compile mode @<:@disabled@:>@])],
87 ,
88 [enable_pedantic="no"]
89)
90
91AC_ARG_ENABLE(
92 [doc],
93 [AS_HELP_STRING([--enable-doc],[enable installation of documents @<:@disabled@:>@])],
94 ,
95 [enable_doc="no"]
96)
97
98AC_ARG_ENABLE(
99 [api-doc],
100 [AS_HELP_STRING([--enable-api-doc],[enable generation and installation of api documents @<:@disabled@:>@])],
101 ,
102 [enable_api_doc="no"]
103)
104
105AC_ARG_WITH(
106 [apidocdir],
107 [AS_HELP_STRING([--with-apidocdir],[put API documents at this directory @<:@HTMLDIR/api@:>@])],
108 [apidocdir="${with_apidocdir}"],
109 [apidocdir="\$(htmldir)/api"]
110)
111
112dnl Checks for programs.
113AC_PROG_CPP
114AC_PROG_INSTALL
115AC_PROG_LN_S
116AC_PROG_MKDIR_P
117AC_PROG_SED
118AC_PROG_MAKE_SET
119
120dnl Add libtool support.
121ifdef(
122 [LT_INIT],
123 [
124 LT_INIT([win32-dll])
125 LT_LANG([Windows Resource])
126 ],
127 [
128 AC_LIBTOOL_WIN32_DLL
129 AC_LIBTOOL_RC
130 AC_PROG_LIBTOOL
131 ]
132)
133
134dnl Checks for header files.
135AC_HEADER_STDC
136AC_HEADER_SYS_WAIT
137AC_CHECK_HEADERS([ \
138 errno.h fcntl.h malloc.h stdlib.h \
139 inttypes.h string.h strings.h sys/time.h \
140 unistd.h locale.h getopt.h dlfcn.h utmp.h \
141])
142
143AC_CHECK_PROGS([DOXYGEN],[doxygen])
144test "${enable_api_doc}" = "yes" -a -z "${DOXYGEN}" && AC_MSG_ERROR([doxygen is required for api doc])
145
146dnl These required for svn checkout
147AC_ARG_VAR([XSLTPROC], [xsltproc utility])
148AC_ARG_VAR([SVN], [subversion utility])
149AC_ARG_VAR([WGET], [wget utility])
150AC_ARG_VAR([WGET_OPTS], [wget options])
151AC_ARG_VAR([TR], [tr utility])
152AC_CHECK_PROGS([XSLTPROC],[xsltproc])
153AC_CHECK_PROGS([SVN],[svn])
154AC_CHECK_PROGS([WGET],[wget])
155AC_CHECK_PROGS([TR],[tr])
156test -z "${WGET_OPTS}" && WGET_OPTS="-nv"
157
158dnl svn checkout dependencies
159if test "${svn_checkout}" = "yes"; then
160 AC_MSG_CHECKING([XSLTPROC requirement])
161 if test -n "${XSLTPROC}"; then
162 AC_MSG_RESULT([ok])
163 else
164 if test "${enable_doc}" = "yes"; then
165 AC_MSG_ERROR([Missing XSLTPROC svn build with doc])
166 else
167 AC_MSG_WARN(["make dist" will not work])
168 fi
169 fi
170
171 AC_MSG_CHECKING([svn doc build dependencies])
172 if test -n "${SVN}" -a -n "${TR}" -a -n "${WGET}"; then
173 AC_MSG_RESULT([ok])
174 else
175 if test "${enable_doc}" = "yes"; then
176 AC_MSG_ERROR([Missing SVN, TR or WGET for svn doc build])
177 else
178 AC_MSG_WARN(["make dist" will not work])
179 fi
180 fi
181fi
182
183AC_ARG_VAR([LTLIB_CFLAGS], [C compiler flags for libltdl])
184AC_ARG_VAR([LTLIB_LIBS], [linker flags for libltdl])
185if test -z "${LTLIB_LIBS}"; then
186 AC_CHECK_LIB(
187 [ltdl],
188 [lt_dlopen],
189 [LTLIB_LIBS="-lltdl"],
190 [AC_MSG_ERROR([ltdl not found, please install libltdl and/or libtool])]
191 )
192
193fi
194saved_CFLAGS="${CFLAGS}"
195CFLAGS="${CFLAGS} ${LTLIB_CFLAGS}"
196AC_CHECK_HEADER(
197 [ltdl.h],
198 ,
199 [AC_MSG_ERROR([ltdl.h not found, please install libltdl and/or libtool])]
200)
201CFLAGS="${saved_CFLAGS}"
202
203PKG_CHECK_MODULES(
204 [OPENSSL],
205 [libcrypto >= 0.9.7],
206 ,
207 [PKG_CHECK_MODULES(
208 [OPENSSL],
209 [openssl >= 0.9.7],
210 ,
211 [AC_CHECK_LIB(
212 [crypto],
213 [RSA_version],
214 [OPENSSL_LIBS="-lcrypto"],
215 [AC_MSG_ERROR([Cannot find OpenSSL])]
216 )]
217 )]
218)
219
220pkgconfigdir="\$(libdir)/pkgconfig"
221
222AC_SUBST([pkgconfigdir])
223AC_SUBST([apidocdir])
224AC_SUBST([LIBP11_VERSION_MAJOR])
225AC_SUBST([LIBP11_VERSION_MINOR])
226AC_SUBST([LIBP11_VERSION_FIX])
227AC_SUBST([LIBP11_LT_CURRENT])
228AC_SUBST([LIBP11_LT_REVISION])
229AC_SUBST([LIBP11_LT_AGE])
230AC_SUBST([LIBP11_LT_OLDEST])
231AC_SUBST([WIN_LIBPREFIX])
232
233AM_CONDITIONAL([SVN_CHECKOUT], [test "${svn_checkout}" = "yes"])
234AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
235AM_CONDITIONAL([CYGWIN], [test "${CYGWIN}" = "yes"])
236AM_CONDITIONAL([ENABLE_DOC], [test "${enable_doc}" = "yes"])
237AM_CONDITIONAL([ENABLE_API_DOC], [test "${enable_api_doc}" = "yes"])
238
239if test "${enable_pedantic}" = "yes"; then
240 enable_strict="yes";
241 CFLAGS="${CFLAGS} -pedantic"
242fi
243if test "${enable_strict}" = "yes"; then
244 CFLAGS="${CFLAGS} -Wall -Wextra"
245fi
246
247AC_CONFIG_FILES([
248 Makefile
249 src/Makefile
250 src/libp11.pc
251 src/versioninfo.rc
252 doc/Makefile
253 doc/doxygen.conf
254 doc/nonpersistent/Makefile
255])
256AC_OUTPUT
257
258cat <<EOF
259
260libp11 has been configured with the following options:
261
262
263Version: ${PACKAGE_VERSION}
264Libraries: $(eval eval eval echo "${libdir}")
265
266doc support: ${enable_doc}
267api doc support: ${enable_api_doc}
268
269Host: ${host}
270Compiler: ${CC}
271Preprocessor flags: ${CPPFLAGS}
272Compiler flags: ${CFLAGS}
273Linker flags: ${LDFLAGS}
274Libraries: ${LIBS}
275
276LTLIB_CFLAGS: ${LTLIB_CFLAGS}
277LTLIB_LIBS: ${LTLIB_LIBS}
278OPENSSL_CFLAGS: ${OPENSSL_CFLAGS}
279OPENSSL_LIBS: ${OPENSSL_LIBS}
280
281EOF
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..397b302
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,26 @@
1MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2
3if ENABLE_DOC
4SUBDIRS = nonpersistent
5endif
6DIST_SUBDIRS = nonpersistent
7
8dist_doc_DATA = README
9dist_noinst_DATA = $(srcdir)/doxygen-footer.html $(srcdir)/*.gif
10
11if ENABLE_API_DOC
12
13apidoc_DATA=api.out/html/*
14
15api.out/html/*: api.out
16api.out: $(top_srcdir)/src/*.h \
17 $(srcdir)/*.gif \
18 doxygen.conf
19 -rm -fr api.out
20 $(DOXYGEN) doxygen.conf
21 cp "$(srcdir)"/*.gif api.out/html
22
23endif
24
25clean-local:
26 -rm -fr api.out
diff --git a/doc/README b/doc/README
new file mode 100644
index 0000000..9019ef0
--- /dev/null
+++ b/doc/README
@@ -0,0 +1,10 @@
1This directory contains a snapshot of the LibP11 Wiki
2=====================================================
3
4The original wiki page is at http://www.opensc-project.org/libp11/
5and includes a bug tracker and source browser.
6
7The wiki was transformed to html using the export-wiki shell
8script and xsl style sheet. The original version is at
9 http://www.twdata.org/trac-howto/
10
diff --git a/doc/doxygen.conf.in b/doc/doxygen.conf.in
new file mode 100644
index 0000000..f2876fb
--- /dev/null
+++ b/doc/doxygen.conf.in
@@ -0,0 +1,1310 @@
1# Doxyfile 1.5.4
2
3# This file describes the settings to be used by the documentation system
4# doxygen (www.doxygen.org) for a project
5#
6# All text after a hash (#) is considered a comment and will be ignored
7# The format is:
8# TAG = value [value, ...]
9# For lists items can also be appended using:
10# TAG += value [value, ...]
11# Values that contain spaces should be placed between quotes (" ")
12
13#---------------------------------------------------------------------------
14# Project related configuration options
15#---------------------------------------------------------------------------
16
17# This tag specifies the encoding used for all characters in the config file that
18# follow. The default is UTF-8 which is also the encoding used for all text before
19# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
20# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
21# possible encodings.
22
23DOXYFILE_ENCODING = UTF-8
24
25# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
26# by quotes) that should identify the project.
27
28PROJECT_NAME = libp11
29
30# The PROJECT_NUMBER tag can be used to enter a project or revision number.
31# This could be handy for archiving the generated documentation or
32# if some version control system is used.
33
34PROJECT_NUMBER = @VERSION@
35
36# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
37# base path where the generated documentation will be put.
38# If a relative path is entered, it will be relative to the location
39# where doxygen was started. If left blank the current directory will be used.
40
41OUTPUT_DIRECTORY = api.out
42
43# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
44# 4096 sub-directories (in 2 levels) under the output directory of each output
45# format and will distribute the generated files over these directories.
46# Enabling this option can be useful when feeding doxygen a huge amount of
47# source files, where putting all generated files in the same directory would
48# otherwise cause performance problems for the file system.
49
50CREATE_SUBDIRS = NO
51
52# The OUTPUT_LANGUAGE tag is used to specify the language in which all
53# documentation generated by doxygen is written. Doxygen will use this
54# information to generate all constant output in the proper language.
55# The default language is English, other supported languages are:
56# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
57# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
58# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
59# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
60# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
61
62OUTPUT_LANGUAGE = English
63
64# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
65# include brief member descriptions after the members that are listed in
66# the file and class documentation (similar to JavaDoc).
67# Set to NO to disable this.
68
69BRIEF_MEMBER_DESC = YES
70
71# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
72# the brief description of a member or function before the detailed description.
73# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
74# brief descriptions will be completely suppressed.
75
76REPEAT_BRIEF = YES
77
78# This tag implements a quasi-intelligent brief description abbreviator
79# that is used to form the text in various listings. Each string
80# in this list, if found as the leading text of the brief description, will be
81# stripped from the text and the result after processing the whole list, is
82# used as the annotated text. Otherwise, the brief description is used as-is.
83# If left blank, the following values are used ("$name" is automatically
84# replaced with the name of the entity): "The $name class" "The $name widget"
85# "The $name file" "is" "provides" "specifies" "contains"
86# "represents" "a" "an" "the"
87
88ABBREVIATE_BRIEF =
89
90# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
91# Doxygen will generate a detailed section even if there is only a brief
92# description.
93
94ALWAYS_DETAILED_SEC = NO
95
96# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
97# inherited members of a class in the documentation of that class as if those
98# members were ordinary class members. Constructors, destructors and assignment
99# operators of the base classes will not be shown.
100
101INLINE_INHERITED_MEMB = NO
102
103# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
104# path before files name in the file list and in the header files. If set
105# to NO the shortest path that makes the file name unique will be used.
106
107FULL_PATH_NAMES = NO
108
109# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
110# can be used to strip a user-defined part of the path. Stripping is
111# only done if one of the specified strings matches the left-hand part of
112# the path. The tag can be used to show relative paths in the file list.
113# If left blank the directory from which doxygen is run is used as the
114# path to strip.
115
116STRIP_FROM_PATH = @top_srcdir@/src
117
118# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
119# the path mentioned in the documentation of a class, which tells
120# the reader which header file to include in order to use a class.
121# If left blank only the name of the header file containing the class
122# definition is used. Otherwise one should specify the include paths that
123# are normally passed to the compiler using the -I flag.
124
125STRIP_FROM_INC_PATH =
126
127# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
128# (but less readable) file names. This can be useful is your file systems
129# doesn't support long names like on DOS, Mac, or CD-ROM.
130
131SHORT_NAMES = NO
132
133# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
134# will interpret the first line (until the first dot) of a JavaDoc-style
135# comment as the brief description. If set to NO, the JavaDoc
136# comments will behave just like regular Qt-style comments
137# (thus requiring an explicit @brief command for a brief description.)
138
139JAVADOC_AUTOBRIEF = YES
140
141# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
142# interpret the first line (until the first dot) of a Qt-style
143# comment as the brief description. If set to NO, the comments
144# will behave just like regular Qt-style comments (thus requiring
145# an explicit \brief command for a brief description.)
146
147QT_AUTOBRIEF = NO
148
149# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
150# treat a multi-line C++ special comment block (i.e. a block of //! or ///
151# comments) as a brief description. This used to be the default behaviour.
152# The new default is to treat a multi-line C++ comment block as a detailed
153# description. Set this tag to YES if you prefer the old behaviour instead.
154
155MULTILINE_CPP_IS_BRIEF = NO
156
157# If the DETAILS_AT_TOP tag is set to YES then Doxygen
158# will output the detailed description near the top, like JavaDoc.
159# If set to NO, the detailed description appears after the member
160# documentation.
161
162DETAILS_AT_TOP = NO
163
164# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
165# member inherits the documentation from any documented member that it
166# re-implements.
167
168INHERIT_DOCS = YES
169
170# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
171# a new page for each member. If set to NO, the documentation of a member will
172# be part of the file/class/namespace that contains it.
173
174SEPARATE_MEMBER_PAGES = NO
175
176# The TAB_SIZE tag can be used to set the number of spaces in a tab.
177# Doxygen uses this value to replace tabs by spaces in code fragments.
178
179TAB_SIZE = 8
180
181# This tag can be used to specify a number of aliases that acts
182# as commands in the documentation. An alias has the form "name=value".
183# For example adding "sideeffect=\par Side Effects:\n" will allow you to
184# put the command \sideeffect (or @sideeffect) in the documentation, which
185# will result in a user-defined paragraph with heading "Side Effects:".
186# You can put \n's in the value part of an alias to insert newlines.
187
188ALIASES =
189
190# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
191# sources only. Doxygen will then generate output that is more tailored for C.
192# For instance, some of the names that are used will be different. The list
193# of all members will be omitted, etc.
194
195OPTIMIZE_OUTPUT_FOR_C = YES
196
197# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
198# sources only. Doxygen will then generate output that is more tailored for Java.
199# For instance, namespaces will be presented as packages, qualified scopes
200# will look different, etc.
201
202OPTIMIZE_OUTPUT_JAVA = NO
203
204# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
205# include (a tag file for) the STL sources as input, then you should
206# set this tag to YES in order to let doxygen match functions declarations and
207# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
208# func(std::string) {}). This also make the inheritance and collaboration
209# diagrams that involve STL classes more complete and accurate.
210
211BUILTIN_STL_SUPPORT = NO
212
213# If you use Microsoft's C++/CLI language, you should set this option to YES to
214# enable parsing support.
215
216CPP_CLI_SUPPORT = NO
217
218# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
219# Doxygen will parse them like normal C++ but will assume all classes use public
220# instead of private inheritance when no explicit protection keyword is present.
221
222SIP_SUPPORT = NO
223
224# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
225# tag is set to YES, then doxygen will reuse the documentation of the first
226# member in the group (if any) for the other members of the group. By default
227# all members of a group must be documented explicitly.
228
229DISTRIBUTE_GROUP_DOC = NO
230
231# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
232# the same type (for instance a group of public functions) to be put as a
233# subgroup of that type (e.g. under the Public Functions section). Set it to
234# NO to prevent subgrouping. Alternatively, this can be done per class using
235# the \nosubgrouping command.
236
237SUBGROUPING = YES
238
239# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct (or union) is
240# documented as struct with the name of the typedef. So
241# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
242# with name TypeT. When disabled the typedef will appear as a member of a file,
243# namespace, or class. And the struct will be named TypeS. This can typically
244# be useful for C code where the coding convention is that all structs are
245# typedef'ed and only the typedef is referenced never the struct's name.
246
247TYPEDEF_HIDES_STRUCT = NO
248
249#---------------------------------------------------------------------------
250# Build related configuration options
251#---------------------------------------------------------------------------
252
253# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
254# documentation are documented, even if no documentation was available.
255# Private class members and static file members will be hidden unless
256# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
257
258EXTRACT_ALL = NO
259
260# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
261# will be included in the documentation.
262
263EXTRACT_PRIVATE = NO
264
265# If the EXTRACT_STATIC tag is set to YES all static members of a file
266# will be included in the documentation.
267
268EXTRACT_STATIC = YES
269
270# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
271# defined locally in source files will be included in the documentation.
272# If set to NO only classes defined in header files are included.
273
274EXTRACT_LOCAL_CLASSES = YES
275
276# This flag is only useful for Objective-C code. When set to YES local
277# methods, which are defined in the implementation section but not in
278# the interface are included in the documentation.
279# If set to NO (the default) only methods in the interface are included.
280
281EXTRACT_LOCAL_METHODS = NO
282
283# If this flag is set to YES, the members of anonymous namespaces will be extracted
284# and appear in the documentation as a namespace called 'anonymous_namespace{file}',
285# where file will be replaced with the base name of the file that contains the anonymous
286# namespace. By default anonymous namespace are hidden.
287
288EXTRACT_ANON_NSPACES = NO
289
290# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
291# undocumented members of documented classes, files or namespaces.
292# If set to NO (the default) these members will be included in the
293# various overviews, but no documentation section is generated.
294# This option has no effect if EXTRACT_ALL is enabled.
295
296HIDE_UNDOC_MEMBERS = NO
297
298# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
299# undocumented classes that are normally visible in the class hierarchy.
300# If set to NO (the default) these classes will be included in the various
301# overviews. This option has no effect if EXTRACT_ALL is enabled.
302
303HIDE_UNDOC_CLASSES = NO
304
305# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
306# friend (class|struct|union) declarations.
307# If set to NO (the default) these declarations will be included in the
308# documentation.
309
310HIDE_FRIEND_COMPOUNDS = NO
311
312# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
313# documentation blocks found inside the body of a function.
314# If set to NO (the default) these blocks will be appended to the
315# function's detailed documentation block.
316
317HIDE_IN_BODY_DOCS = NO
318
319# The INTERNAL_DOCS tag determines if documentation
320# that is typed after a \internal command is included. If the tag is set
321# to NO (the default) then the documentation will be excluded.
322# Set it to YES to include the internal documentation.
323
324INTERNAL_DOCS = NO
325
326# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
327# file names in lower-case letters. If set to YES upper-case letters are also
328# allowed. This is useful if you have classes or files whose names only differ
329# in case and if your file system supports case sensitive file names. Windows
330# and Mac users are advised to set this option to NO.
331
332CASE_SENSE_NAMES = YES
333
334# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
335# will show members with their full class and namespace scopes in the
336# documentation. If set to YES the scope will be hidden.
337
338HIDE_SCOPE_NAMES = YES
339
340# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
341# will put a list of the files that are included by a file in the documentation
342# of that file.
343
344SHOW_INCLUDE_FILES = YES
345
346# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
347# is inserted in the documentation for inline members.
348
349INLINE_INFO = YES
350
351# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
352# will sort the (detailed) documentation of file and class members
353# alphabetically by member name. If set to NO the members will appear in
354# declaration order.
355
356SORT_MEMBER_DOCS = YES
357
358# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
359# brief documentation of file, namespace and class members alphabetically
360# by member name. If set to NO (the default) the members will appear in
361# declaration order.
362
363SORT_BRIEF_DOCS = NO
364
365# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
366# sorted by fully-qualified names, including namespaces. If set to
367# NO (the default), the class list will be sorted only by class name,
368# not including the namespace part.
369# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
370# Note: This option applies only to the class list, not to the
371# alphabetical list.
372
373SORT_BY_SCOPE_NAME = NO
374
375# The GENERATE_TODOLIST tag can be used to enable (YES) or
376# disable (NO) the todo list. This list is created by putting \todo
377# commands in the documentation.
378
379GENERATE_TODOLIST = YES
380
381# The GENERATE_TESTLIST tag can be used to enable (YES) or
382# disable (NO) the test list. This list is created by putting \test
383# commands in the documentation.
384
385GENERATE_TESTLIST = YES
386
387# The GENERATE_BUGLIST tag can be used to enable (YES) or
388# disable (NO) the bug list. This list is created by putting \bug
389# commands in the documentation.
390
391GENERATE_BUGLIST = YES
392
393# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
394# disable (NO) the deprecated list. This list is created by putting
395# \deprecated commands in the documentation.
396
397GENERATE_DEPRECATEDLIST= YES
398
399# The ENABLED_SECTIONS tag can be used to enable conditional
400# documentation sections, marked by \if sectionname ... \endif.
401
402ENABLED_SECTIONS =
403
404# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
405# the initial value of a variable or define consists of for it to appear in
406# the documentation. If the initializer consists of more lines than specified
407# here it will be hidden. Use a value of 0 to hide initializers completely.
408# The appearance of the initializer of individual variables and defines in the
409# documentation can be controlled using \showinitializer or \hideinitializer
410# command in the documentation regardless of this setting.
411
412MAX_INITIALIZER_LINES = 30
413
414# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
415# at the bottom of the documentation of classes and structs. If set to YES the
416# list will mention the files that were used to generate the documentation.
417
418SHOW_USED_FILES = YES
419
420# If the sources in your project are distributed over multiple directories
421# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
422# in the documentation. The default is NO.
423
424SHOW_DIRECTORIES = YES
425
426# The FILE_VERSION_FILTER tag can be used to specify a program or script that
427# doxygen should invoke to get the current version for each file (typically from the
428# version control system). Doxygen will invoke the program by executing (via
429# popen()) the command <command> <input-file>, where <command> is the value of
430# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
431# provided by doxygen. Whatever the program writes to standard output
432# is used as the file version. See the manual for examples.
433
434FILE_VERSION_FILTER =
435
436#---------------------------------------------------------------------------
437# configuration options related to warning and progress messages
438#---------------------------------------------------------------------------
439
440# The QUIET tag can be used to turn on/off the messages that are generated
441# by doxygen. Possible values are YES and NO. If left blank NO is used.
442
443QUIET = NO
444
445# The WARNINGS tag can be used to turn on/off the warning messages that are
446# generated by doxygen. Possible values are YES and NO. If left blank
447# NO is used.
448
449WARNINGS = YES
450
451# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
452# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
453# automatically be disabled.
454
455WARN_IF_UNDOCUMENTED = NO
456
457# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
458# potential errors in the documentation, such as not documenting some
459# parameters in a documented function, or documenting parameters that
460# don't exist or using markup commands wrongly.
461
462WARN_IF_DOC_ERROR = YES
463
464# This WARN_NO_PARAMDOC option can be abled to get warnings for
465# functions that are documented, but have no documentation for their parameters
466# or return value. If set to NO (the default) doxygen will only warn about
467# wrong or incomplete parameter documentation, but not about the absence of
468# documentation.
469
470WARN_NO_PARAMDOC = NO
471
472# The WARN_FORMAT tag determines the format of the warning messages that
473# doxygen can produce. The string should contain the $file, $line, and $text
474# tags, which will be replaced by the file and line number from which the
475# warning originated and the warning text. Optionally the format may contain
476# $version, which will be replaced by the version of the file (if it could
477# be obtained via FILE_VERSION_FILTER)
478
479WARN_FORMAT = "$file:$line: $text "
480
481# The WARN_LOGFILE tag can be used to specify a file to which warning
482# and error messages should be written. If left blank the output is written
483# to stderr.
484
485WARN_LOGFILE =
486
487#---------------------------------------------------------------------------
488# configuration options related to the input files
489#---------------------------------------------------------------------------
490
491# The INPUT tag can be used to specify the files and/or directories that contain
492# documented source files. You may enter file names like "myfile.cpp" or
493# directories like "/usr/src/myproject". Separate the files or directories
494# with spaces.
495
496INPUT = @top_srcdir@/src
497
498# This tag can be used to specify the character encoding of the source files that
499# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
500# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
501# See http://www.gnu.org/software/libiconv for the list of possible encodings.
502
503INPUT_ENCODING = UTF-8
504
505# If the value of the INPUT tag contains directories, you can use the
506# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
507# and *.h) to filter out the source-files in the directories. If left
508# blank the following patterns are tested:
509# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
510# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
511
512FILE_PATTERNS = libp11.h
513
514# The RECURSIVE tag can be used to turn specify whether or not subdirectories
515# should be searched for input files as well. Possible values are YES and NO.
516# If left blank NO is used.
517
518RECURSIVE = NO
519
520# The EXCLUDE tag can be used to specify files and/or directories that should
521# excluded from the INPUT source files. This way you can easily exclude a
522# subdirectory from a directory tree whose root is specified with the INPUT tag.
523
524EXCLUDE =
525
526# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
527# directories that are symbolic links (a Unix filesystem feature) are excluded
528# from the input.
529
530EXCLUDE_SYMLINKS = NO
531
532# If the value of the INPUT tag contains directories, you can use the
533# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
534# certain files from those directories. Note that the wildcards are matched
535# against the file with absolute path, so to exclude all test directories
536# for example use the pattern */test/*
537
538EXCLUDE_PATTERNS = */.svn/*
539
540# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
541# (namespaces, classes, functions, etc.) that should be excluded from the output.
542# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
543# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
544
545EXCLUDE_SYMBOLS =
546
547# The EXAMPLE_PATH tag can be used to specify one or more files or
548# directories that contain example code fragments that are included (see
549# the \include command).
550
551EXAMPLE_PATH =
552
553# If the value of the EXAMPLE_PATH tag contains directories, you can use the
554# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
555# and *.h) to filter out the source-files in the directories. If left
556# blank all files are included.
557
558EXAMPLE_PATTERNS =
559
560# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
561# searched for input files to be used with the \include or \dontinclude
562# commands irrespective of the value of the RECURSIVE tag.
563# Possible values are YES and NO. If left blank NO is used.
564
565EXAMPLE_RECURSIVE = NO
566
567# The IMAGE_PATH tag can be used to specify one or more files or
568# directories that contain image that are included in the documentation (see
569# the \image command).
570
571IMAGE_PATH =
572
573# The INPUT_FILTER tag can be used to specify a program that doxygen should
574# invoke to filter for each input file. Doxygen will invoke the filter program
575# by executing (via popen()) the command <filter> <input-file>, where <filter>
576# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
577# input file. Doxygen will then use the output that the filter program writes
578# to standard output. If FILTER_PATTERNS is specified, this tag will be
579# ignored.
580
581INPUT_FILTER =
582
583# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
584# basis. Doxygen will compare the file name with each pattern and apply the
585# filter if there is a match. The filters are a list of the form:
586# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
587# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
588# is applied to all files.
589
590FILTER_PATTERNS =
591
592# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
593# INPUT_FILTER) will be used to filter the input files when producing source
594# files to browse (i.e. when SOURCE_BROWSER is set to YES).
595
596FILTER_SOURCE_FILES = NO
597
598#---------------------------------------------------------------------------
599# configuration options related to source browsing
600#---------------------------------------------------------------------------
601
602# If the SOURCE_BROWSER tag is set to YES then a list of source files will
603# be generated. Documented entities will be cross-referenced with these sources.
604# Note: To get rid of all source code in the generated output, make sure also
605# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH
606# then you must also enable this option. If you don't then doxygen will produce
607# a warning and turn it on anyway
608
609SOURCE_BROWSER = YES
610
611# Setting the INLINE_SOURCES tag to YES will include the body
612# of functions and classes directly in the documentation.
613
614INLINE_SOURCES = NO
615
616# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
617# doxygen to hide any special comment blocks from generated source code
618# fragments. Normal C and C++ comments will always remain visible.
619
620STRIP_CODE_COMMENTS = YES
621
622# If the REFERENCED_BY_RELATION tag is set to YES (the default)
623# then for each documented function all documented
624# functions referencing it will be listed.
625
626REFERENCED_BY_RELATION = YES
627
628# If the REFERENCES_RELATION tag is set to YES (the default)
629# then for each documented function all documented entities
630# called/used by that function will be listed.
631
632REFERENCES_RELATION = YES
633
634# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
635# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
636# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
637# link to the source code. Otherwise they will link to the documentstion.
638
639REFERENCES_LINK_SOURCE = YES
640
641# If the USE_HTAGS tag is set to YES then the references to source code
642# will point to the HTML generated by the htags(1) tool instead of doxygen
643# built-in source browser. The htags tool is part of GNU's global source
644# tagging system (see http://www.gnu.org/software/global/global.html). You
645# will need version 4.8.6 or higher.
646
647USE_HTAGS = NO
648
649# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
650# will generate a verbatim copy of the header file for each class for
651# which an include is specified. Set to NO to disable this.
652
653VERBATIM_HEADERS = YES
654
655#---------------------------------------------------------------------------
656# configuration options related to the alphabetical class index
657#---------------------------------------------------------------------------
658
659# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
660# of all compounds will be generated. Enable this if the project
661# contains a lot of classes, structs, unions or interfaces.
662
663ALPHABETICAL_INDEX = NO
664
665# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
666# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
667# in which this list will be split (can be a number in the range [1..20])
668
669COLS_IN_ALPHA_INDEX = 5
670
671# In case all classes in a project start with a common prefix, all
672# classes will be put under the same header in the alphabetical index.
673# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
674# should be ignored while generating the index headers.
675
676IGNORE_PREFIX =
677
678#---------------------------------------------------------------------------
679# configuration options related to the HTML output
680#---------------------------------------------------------------------------
681
682# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
683# generate HTML output.
684
685GENERATE_HTML = YES
686
687# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
688# If a relative path is entered the value of OUTPUT_DIRECTORY will be
689# put in front of it. If left blank `html' will be used as the default path.
690
691HTML_OUTPUT = html
692
693# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
694# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
695# doxygen will generate files with .html extension.
696
697HTML_FILE_EXTENSION = .html
698
699# The HTML_HEADER tag can be used to specify a personal HTML header for
700# each generated HTML page. If it is left blank doxygen will generate a
701# standard header.
702
703HTML_HEADER =
704
705# The HTML_FOOTER tag can be used to specify a personal HTML footer for
706# each generated HTML page. If it is left blank doxygen will generate a
707# standard footer.
708
709HTML_FOOTER = @srcdir@/doxygen-footer.html
710
711# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
712# style sheet that is used by each HTML page. It can be used to
713# fine-tune the look of the HTML output. If the tag is left blank doxygen
714# will generate a default style sheet. Note that doxygen will try to copy
715# the style sheet file to the HTML output directory, so don't put your own
716# stylesheet in the HTML output directory as well, or it will be erased!
717
718HTML_STYLESHEET =
719
720# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
721# files or namespaces will be aligned in HTML using tables. If set to
722# NO a bullet list will be used.
723
724HTML_ALIGN_MEMBERS = YES
725
726# If the GENERATE_HTMLHELP tag is set to YES, additional index files
727# will be generated that can be used as input for tools like the
728# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
729# of the generated HTML documentation.
730
731GENERATE_HTMLHELP = NO
732
733# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
734# documentation will contain sections that can be hidden and shown after the
735# page has loaded. For this to work a browser that supports
736# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
737# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
738
739HTML_DYNAMIC_SECTIONS = NO
740
741# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
742# be used to specify the file name of the resulting .chm file. You
743# can add a path in front of the file if the result should not be
744# written to the html output directory.
745
746CHM_FILE =
747
748# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
749# be used to specify the location (absolute path including file name) of
750# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
751# the HTML help compiler on the generated index.hhp.
752
753HHC_LOCATION =
754
755# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
756# controls if a separate .chi index file is generated (YES) or that
757# it should be included in the master .chm file (NO).
758
759GENERATE_CHI = NO
760
761# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
762# controls whether a binary table of contents is generated (YES) or a
763# normal table of contents (NO) in the .chm file.
764
765BINARY_TOC = NO
766
767# The TOC_EXPAND flag can be set to YES to add extra items for group members
768# to the contents of the HTML help documentation and to the tree view.
769
770TOC_EXPAND = NO
771
772# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
773# top of each HTML page. The value NO (the default) enables the index and
774# the value YES disables it.
775
776DISABLE_INDEX = NO
777
778# This tag can be used to set the number of enum values (range [1..20])
779# that doxygen will group on one line in the generated HTML documentation.
780
781ENUM_VALUES_PER_LINE = 4
782
783# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
784# generated containing a tree-like index structure (just like the one that
785# is generated for HTML Help). For this to work a browser that supports
786# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
787# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
788# probably better off using the HTML help feature.
789
790GENERATE_TREEVIEW = NO
791
792# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
793# used to set the initial width (in pixels) of the frame in which the tree
794# is shown.
795
796TREEVIEW_WIDTH = 250
797
798#---------------------------------------------------------------------------
799# configuration options related to the LaTeX output
800#---------------------------------------------------------------------------
801
802# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
803# generate Latex output.
804
805GENERATE_LATEX = NO
806
807# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
808# If a relative path is entered the value of OUTPUT_DIRECTORY will be
809# put in front of it. If left blank `latex' will be used as the default path.
810
811LATEX_OUTPUT = latex
812
813# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
814# invoked. If left blank `latex' will be used as the default command name.
815
816LATEX_CMD_NAME = latex
817
818# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
819# generate index for LaTeX. If left blank `makeindex' will be used as the
820# default command name.
821
822MAKEINDEX_CMD_NAME = makeindex
823
824# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
825# LaTeX documents. This may be useful for small projects and may help to
826# save some trees in general.
827
828COMPACT_LATEX = NO
829
830# The PAPER_TYPE tag can be used to set the paper type that is used
831# by the printer. Possible values are: a4, a4wide, letter, legal and
832# executive. If left blank a4wide will be used.
833
834PAPER_TYPE = a4wide
835
836# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
837# packages that should be included in the LaTeX output.
838
839EXTRA_PACKAGES =
840
841# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
842# the generated latex document. The header should contain everything until
843# the first chapter. If it is left blank doxygen will generate a
844# standard header. Notice: only use this tag if you know what you are doing!
845
846LATEX_HEADER =
847
848# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
849# is prepared for conversion to pdf (using ps2pdf). The pdf file will
850# contain links (just like the HTML output) instead of page references
851# This makes the output suitable for online browsing using a pdf viewer.
852
853PDF_HYPERLINKS = NO
854
855# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
856# plain latex in the generated Makefile. Set this option to YES to get a
857# higher quality PDF documentation.
858
859USE_PDFLATEX = NO
860
861# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
862# command to the generated LaTeX files. This will instruct LaTeX to keep
863# running if errors occur, instead of asking the user for help.
864# This option is also used when generating formulas in HTML.
865
866LATEX_BATCHMODE = NO
867
868# If LATEX_HIDE_INDICES is set to YES then doxygen will not
869# include the index chapters (such as File Index, Compound Index, etc.)
870# in the output.
871
872LATEX_HIDE_INDICES = NO
873
874#---------------------------------------------------------------------------
875# configuration options related to the RTF output
876#---------------------------------------------------------------------------
877
878# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
879# The RTF output is optimized for Word 97 and may not look very pretty with
880# other RTF readers or editors.
881
882GENERATE_RTF = NO
883
884# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
885# If a relative path is entered the value of OUTPUT_DIRECTORY will be
886# put in front of it. If left blank `rtf' will be used as the default path.
887
888RTF_OUTPUT = rtf
889
890# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
891# RTF documents. This may be useful for small projects and may help to
892# save some trees in general.
893
894COMPACT_RTF = NO
895
896# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
897# will contain hyperlink fields. The RTF file will
898# contain links (just like the HTML output) instead of page references.
899# This makes the output suitable for online browsing using WORD or other
900# programs which support those fields.
901# Note: wordpad (write) and others do not support links.
902
903RTF_HYPERLINKS = NO
904
905# Load stylesheet definitions from file. Syntax is similar to doxygen's
906# config file, i.e. a series of assignments. You only have to provide
907# replacements, missing definitions are set to their default value.
908
909RTF_STYLESHEET_FILE =
910
911# Set optional variables used in the generation of an rtf document.
912# Syntax is similar to doxygen's config file.
913
914RTF_EXTENSIONS_FILE =
915
916#---------------------------------------------------------------------------
917# configuration options related to the man page output
918#---------------------------------------------------------------------------
919
920# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
921# generate man pages
922
923GENERATE_MAN = NO
924
925# The MAN_OUTPUT tag is used to specify where the man pages will be put.
926# If a relative path is entered the value of OUTPUT_DIRECTORY will be
927# put in front of it. If left blank `man' will be used as the default path.
928
929MAN_OUTPUT = man
930
931# The MAN_EXTENSION tag determines the extension that is added to
932# the generated man pages (default is the subroutine's section .3)
933
934MAN_EXTENSION = .3
935
936# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
937# then it will generate one additional man file for each entity
938# documented in the real man page(s). These additional files
939# only source the real man page, but without them the man command
940# would be unable to find the correct page. The default is NO.
941
942MAN_LINKS = NO
943
944#---------------------------------------------------------------------------
945# configuration options related to the XML output
946#---------------------------------------------------------------------------
947
948# If the GENERATE_XML tag is set to YES Doxygen will
949# generate an XML file that captures the structure of
950# the code including all documentation.
951
952GENERATE_XML = NO
953
954# The XML_OUTPUT tag is used to specify where the XML pages will be put.
955# If a relative path is entered the value of OUTPUT_DIRECTORY will be
956# put in front of it. If left blank `xml' will be used as the default path.
957
958XML_OUTPUT = xml
959
960# The XML_SCHEMA tag can be used to specify an XML schema,
961# which can be used by a validating XML parser to check the
962# syntax of the XML files.
963
964XML_SCHEMA =
965
966# The XML_DTD tag can be used to specify an XML DTD,
967# which can be used by a validating XML parser to check the
968# syntax of the XML files.
969
970XML_DTD =
971
972# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
973# dump the program listings (including syntax highlighting
974# and cross-referencing information) to the XML output. Note that
975# enabling this will significantly increase the size of the XML output.
976
977XML_PROGRAMLISTING = YES
978
979#---------------------------------------------------------------------------
980# configuration options for the AutoGen Definitions output
981#---------------------------------------------------------------------------
982
983# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
984# generate an AutoGen Definitions (see autogen.sf.net) file
985# that captures the structure of the code including all
986# documentation. Note that this feature is still experimental
987# and incomplete at the moment.
988
989GENERATE_AUTOGEN_DEF = NO
990
991#---------------------------------------------------------------------------
992# configuration options related to the Perl module output
993#---------------------------------------------------------------------------
994
995# If the GENERATE_PERLMOD tag is set to YES Doxygen will
996# generate a Perl module file that captures the structure of
997# the code including all documentation. Note that this
998# feature is still experimental and incomplete at the
999# moment.
1000
1001GENERATE_PERLMOD = NO
1002
1003# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
1004# the necessary Makefile rules, Perl scripts and LaTeX code to be able
1005# to generate PDF and DVI output from the Perl module output.
1006
1007PERLMOD_LATEX = NO
1008
1009# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
1010# nicely formatted so it can be parsed by a human reader. This is useful
1011# if you want to understand what is going on. On the other hand, if this
1012# tag is set to NO the size of the Perl module output will be much smaller
1013# and Perl will parse it just the same.
1014
1015PERLMOD_PRETTY = YES
1016
1017# The names of the make variables in the generated doxyrules.make file
1018# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
1019# This is useful so different doxyrules.make files included by the same
1020# Makefile don't overwrite each other's variables.
1021
1022PERLMOD_MAKEVAR_PREFIX =
1023
1024#---------------------------------------------------------------------------
1025# Configuration options related to the preprocessor
1026#---------------------------------------------------------------------------
1027
1028# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
1029# evaluate all C-preprocessor directives found in the sources and include
1030# files.
1031
1032ENABLE_PREPROCESSING = YES
1033
1034# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
1035# names in the source code. If set to NO (the default) only conditional
1036# compilation will be performed. Macro expansion can be done in a controlled
1037# way by setting EXPAND_ONLY_PREDEF to YES.
1038
1039MACRO_EXPANSION = NO
1040
1041# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
1042# then the macro expansion is limited to the macros specified with the
1043# PREDEFINED and EXPAND_AS_DEFINED tags.
1044
1045EXPAND_ONLY_PREDEF = NO
1046
1047# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
1048# in the INCLUDE_PATH (see below) will be search if a #include is found.
1049
1050SEARCH_INCLUDES = YES
1051
1052# The INCLUDE_PATH tag can be used to specify one or more directories that
1053# contain include files that are not input files but should be processed by
1054# the preprocessor.
1055
1056INCLUDE_PATH =
1057
1058# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
1059# patterns (like *.h and *.hpp) to filter out the header-files in the
1060# directories. If left blank, the patterns specified with FILE_PATTERNS will
1061# be used.
1062
1063INCLUDE_FILE_PATTERNS =
1064
1065# The PREDEFINED tag can be used to specify one or more macro names that
1066# are defined before the preprocessor is started (similar to the -D option of
1067# gcc). The argument of the tag is a list of macros of the form: name
1068# or name=definition (no spaces). If the definition and the = are
1069# omitted =1 is assumed. To prevent a macro definition from being
1070# undefined via #undef or recursively expanded use the := operator
1071# instead of the = operator.
1072
1073PREDEFINED =
1074
1075# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
1076# this tag can be used to specify a list of macro names that should be expanded.
1077# The macro definition that is found in the sources will be used.
1078# Use the PREDEFINED tag if you want to use a different macro definition.
1079
1080EXPAND_AS_DEFINED =
1081
1082# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
1083# doxygen's preprocessor will remove all function-like macros that are alone
1084# on a line, have an all uppercase name, and do not end with a semicolon. Such
1085# function macros are typically used for boiler-plate code, and will confuse
1086# the parser if not removed.
1087
1088SKIP_FUNCTION_MACROS = YES
1089
1090#---------------------------------------------------------------------------
1091# Configuration::additions related to external references
1092#---------------------------------------------------------------------------
1093
1094# The TAGFILES option can be used to specify one or more tagfiles.
1095# Optionally an initial location of the external documentation
1096# can be added for each tagfile. The format of a tag file without
1097# this location is as follows:
1098# TAGFILES = file1 file2 ...
1099# Adding location for the tag files is done as follows:
1100# TAGFILES = file1=loc1 "file2 = loc2" ...
1101# where "loc1" and "loc2" can be relative or absolute paths or
1102# URLs. If a location is present for each tag, the installdox tool
1103# does not have to be run to correct the links.
1104# Note that each tag file must have a unique name
1105# (where the name does NOT include the path)
1106# If a tag file is not located in the directory in which doxygen
1107# is run, you must also specify the path to the tagfile here.
1108
1109TAGFILES =
1110
1111# When a file name is specified after GENERATE_TAGFILE, doxygen will create
1112# a tag file that is based on the input files it reads.
1113
1114GENERATE_TAGFILE =
1115
1116# If the ALLEXTERNALS tag is set to YES all external classes will be listed
1117# in the class index. If set to NO only the inherited external classes
1118# will be listed.
1119
1120ALLEXTERNALS = NO
1121
1122# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
1123# in the modules index. If set to NO, only the current project's groups will
1124# be listed.
1125
1126EXTERNAL_GROUPS = YES
1127
1128# The PERL_PATH should be the absolute path and name of the perl script
1129# interpreter (i.e. the result of `which perl').
1130
1131PERL_PATH = /usr/bin/perl
1132
1133#---------------------------------------------------------------------------
1134# Configuration options related to the dot tool
1135#---------------------------------------------------------------------------
1136
1137# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
1138# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
1139# or super classes. Setting the tag to NO turns the diagrams off. Note that
1140# this option is superseded by the HAVE_DOT option below. This is only a
1141# fallback. It is recommended to install and use dot, since it yields more
1142# powerful graphs.
1143
1144CLASS_DIAGRAMS = YES
1145
1146# You can define message sequence charts within doxygen comments using the \msc
1147# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
1148# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
1149# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
1150# be found in the default search path.
1151
1152MSCGEN_PATH =
1153
1154# If set to YES, the inheritance and collaboration graphs will hide
1155# inheritance and usage relations if the target is undocumented
1156# or is not a class.
1157
1158HIDE_UNDOC_RELATIONS = YES
1159
1160# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
1161# available from the path. This tool is part of Graphviz, a graph visualization
1162# toolkit from AT&T and Lucent Bell Labs. The other options in this section
1163# have no effect if this option is set to NO (the default)
1164
1165HAVE_DOT = NO
1166
1167# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
1168# will generate a graph for each documented class showing the direct and
1169# indirect inheritance relations. Setting this tag to YES will force the
1170# the CLASS_DIAGRAMS tag to NO.
1171
1172CLASS_GRAPH = YES
1173
1174# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
1175# will generate a graph for each documented class showing the direct and
1176# indirect implementation dependencies (inheritance, containment, and
1177# class references variables) of the class with other documented classes.
1178
1179COLLABORATION_GRAPH = YES
1180
1181# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
1182# will generate a graph for groups, showing the direct groups dependencies
1183
1184GROUP_GRAPHS = YES
1185
1186# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
1187# collaboration diagrams in a style similar to the OMG's Unified Modeling
1188# Language.
1189
1190UML_LOOK = NO
1191
1192# If set to YES, the inheritance and collaboration graphs will show the
1193# relations between templates and their instances.
1194
1195TEMPLATE_RELATIONS = NO
1196
1197# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
1198# tags are set to YES then doxygen will generate a graph for each documented
1199# file showing the direct and indirect include dependencies of the file with
1200# other documented files.
1201
1202INCLUDE_GRAPH = YES
1203
1204# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
1205# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
1206# documented header file showing the documented files that directly or
1207# indirectly include this file.
1208
1209INCLUDED_BY_GRAPH = YES
1210
1211# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
1212# generate a call dependency graph for every global function or class method.
1213# Note that enabling this option will significantly increase the time of a run.
1214# So in most cases it will be better to enable call graphs for selected
1215# functions only using the \callgraph command.
1216
1217CALL_GRAPH = NO
1218
1219# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
1220# generate a caller dependency graph for every global function or class method.
1221# Note that enabling this option will significantly increase the time of a run.
1222# So in most cases it will be better to enable caller graphs for selected
1223# functions only using the \callergraph command.
1224
1225CALLER_GRAPH = NO
1226
1227# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
1228# will graphical hierarchy of all classes instead of a textual one.
1229
1230GRAPHICAL_HIERARCHY = YES
1231
1232# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
1233# then doxygen will show the dependencies a directory has on other directories
1234# in a graphical way. The dependency relations are determined by the #include
1235# relations between the files in the directories.
1236
1237DIRECTORY_GRAPH = YES
1238
1239# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
1240# generated by dot. Possible values are png, jpg, or gif
1241# If left blank png will be used.
1242
1243DOT_IMAGE_FORMAT = png
1244
1245# The tag DOT_PATH can be used to specify the path where the dot tool can be
1246# found. If left blank, it is assumed the dot tool can be found in the path.
1247
1248DOT_PATH =
1249
1250# The DOTFILE_DIRS tag can be used to specify one or more directories that
1251# contain dot files that are included in the documentation (see the
1252# \dotfile command).
1253
1254DOTFILE_DIRS =
1255
1256# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
1257# nodes that will be shown in the graph. If the number of nodes in a graph
1258# becomes larger than this value, doxygen will truncate the graph, which is
1259# visualized by representing a node as a red box. Note that doxygen if the number
1260# of direct children of the root node in a graph is already larger than
1261# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note
1262# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
1263
1264DOT_GRAPH_MAX_NODES = 50
1265
1266# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
1267# graphs generated by dot. A depth value of 3 means that only nodes reachable
1268# from the root by following a path via at most 3 edges will be shown. Nodes
1269# that lay further from the root node will be omitted. Note that setting this
1270# option to 1 or 2 may greatly reduce the computation time needed for large
1271# code bases. Also note that the size of a graph can be further restricted by
1272# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
1273
1274MAX_DOT_GRAPH_DEPTH = 0
1275
1276# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
1277# background. This is disabled by default, which results in a white background.
1278# Warning: Depending on the platform used, enabling this option may lead to
1279# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
1280# read).
1281
1282DOT_TRANSPARENT = NO
1283
1284# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
1285# files in one run (i.e. multiple -o and -T options on the command line). This
1286# makes dot run faster, but since only newer versions of dot (>1.8.10)
1287# support this, this feature is disabled by default.
1288
1289DOT_MULTI_TARGETS = NO
1290
1291# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
1292# generate a legend page explaining the meaning of the various boxes and
1293# arrows in the dot generated graphs.
1294
1295GENERATE_LEGEND = YES
1296
1297# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
1298# remove the intermediate dot files that are used to generate
1299# the various graphs.
1300
1301DOT_CLEANUP = YES
1302
1303#---------------------------------------------------------------------------
1304# Configuration::additions related to the search engine
1305#---------------------------------------------------------------------------
1306
1307# The SEARCHENGINE tag specifies whether or not a search engine should be
1308# used. If set to NO the values of all tags below this one will be ignored.
1309
1310SEARCHENGINE = NO
diff --git a/doc/nonpersistent/Makefile.am b/doc/nonpersistent/Makefile.am
new file mode 100644
index 0000000..e67c6af
--- /dev/null
+++ b/doc/nonpersistent/Makefile.am
@@ -0,0 +1,59 @@
1MAINTAINERCLEANFILES = \
2 $(srcdir)/Makefile.in
3
4wikidir=$(htmldir)/wiki
5
6dist_noinst_SCRIPTS = export-wiki.sh export-wiki.xsl \
7 svn2cl.xsl
8dist_wiki_DATA = wiki.out/*
9dist_noinst_DATA = ChangeLog
10
11if SVN_CHECKOUT
12
13wiki.out/*: wiki.out
14wiki.out:
15 -rm -fr wiki.out
16 test -n "$(WGET)" -a -n "$(SED)" -a -n "$(TR)" -a -n "$(XSLTPROC)"
17 WGET="$(WGET)" WGET_OPTS="$(WGET_OPTS)" SED="$(SED)" TR="$(TR)" XSLTPROC="$(XSLTPROC)" \
18 PROJECT="@PACKAGE_NAME@" \
19 $(SHELL) "$(srcdir)/export-wiki.sh" "$(srcdir)" "wiki.tmp"
20 mv wiki.tmp wiki.out
21
22ChangeLog:
23 test -n "$(SVN)" -a -n "$(XSLTPROC)"
24 if test -d "$(top_srcdir)/.svn"; then \
25 $(SVN) --verbose --xml log "$(top_srcdir)" | \
26 $(XSLTPROC) --nonet --stringparam linelen 75 \
27 --stringparam groupbyday no \
28 --stringparam include-rev no \
29 "$(srcdir)/svn2cl.xsl" - > ChangeLog.tmp; \
30 else \
31 echo "Warning: Unable to generate ChangeLog from none svn checkout" >&2; \
32 echo > ChangeLog.tmp; \
33 fi
34 mv ChangeLog.tmp ChangeLog
35
36else
37
38wiki.out/*: $(abs_builddir)/wiki.out
39$(abs_builddir)/wiki.out:
40 $(LN_S) "$(srcdir)/wiki.out" wiki.out
41
42ChangeLog:
43 $(LN_S) "$(srcdir)/ChangeLog" ChangeLog
44
45endif
46
47distclean-local:
48 -rm -rf wiki.tmp
49 if test -L wiki.out; then \
50 rm -fr wiki.out; \
51 fi
52 -rm -fr ChangeLog.tmp
53 if test -L ChangeLog; then \
54 rm -fr ChangeLog; \
55 fi
56
57maintainer-clean-local:
58 -rm -rf "$(srcdir)/wiki.out"
59 -rm -rf "$(srcdir)/ChangeLog"
diff --git a/doc/nonpersistent/export-wiki.sh b/doc/nonpersistent/export-wiki.sh
new file mode 100755
index 0000000..956fb21
--- /dev/null
+++ b/doc/nonpersistent/export-wiki.sh
@@ -0,0 +1,71 @@
1#!/bin/sh
2
3set -e
4
5test -z "$XSLTPROC" && XSLTPROC="xsltproc"
6test -z "$WGET" && WGET="wget"
7test -z "$WGET_OPTS" && WGET_OPTS="$WGET_OPTS"
8test -z "$SED" && SED="sed"
9test -z "$TR" && TR="tr"
10
11test -z "$SERVER" && SERVER="http://www.opensc-project.org"
12test -z "$PROJECT" && PROJECT="opensc"
13
14SRCDIR=.
15OUTDIR=.
16test -n "$1" && SRCDIR="$1"
17test -n "$2" && OUTDIR="$2"
18
19WIKI="$PROJECT/wiki"
20XSL="$SRCDIR/export-wiki.xsl"
21
22test -f "$SRCDIR"/`basename $0`
23
24test -e "$OUTDIR" && rm -fr "$OUTDIR"
25
26mkdir "$OUTDIR" || exit 1
27
28$WGET $WGET_OPTS $SERVER/$WIKI/TitleIndex -O "$OUTDIR"/TitleIndex.tmp
29
30$SED -e "s#</li>#</li>\n#g" < "$OUTDIR"/TitleIndex.tmp \
31 | grep "\"/$WIKI/[^\"]*\"" \
32 |$SED -e "s#.*\"/$WIKI/\([^\"]*\)\".*#\1#g" \
33 > "$OUTDIR"/WikiWords.tmp
34$SED -e /^Trac/d -e /^Wiki/d -e /^TitleIndex/d -e /^RecentChanges/d \
35 -e /^CamelCase/d -e /^SandBox/d -e /^InterMapTxt/d -e /^InterWiki/d \
36 -e /^InterTrac/d -i "$OUTDIR"/WikiWords.tmp
37
38for A in WikiStart `cat "$OUTDIR"/WikiWords.tmp`
39do
40 F=`echo $A|$SED -e 's/\//_/g'`
41 $WGET $WGET_OPTS $SERVER/$WIKI/$A -O "$OUTDIR"/$F.tmp
42 $XSLTPROC --nonet --output "$OUTDIR"/$F.html "$XSL" "$OUTDIR"/$F.tmp
43 $SED -e "s#<a href=\"/$WIKI/\([^\"]*\)\"#<a href=\"\1.html\"#g" \
44 -i "$OUTDIR"/$F.html
45done
46
47mv "$OUTDIR"/WikiStart.html "$OUTDIR"/index.html
48
49$WGET $WGET_OPTS http://www.opensc-project.org/trac/css/trac.css \
50 -O "$OUTDIR"/trac.css
51
52cat "$OUTDIR"/*.html |grep "<img src=\"/$PROJECT/attachment/wiki" \
53 |$SED -e 's/.*<img src="\/'$PROJECT'\/attachment\/wiki\/\([^"]*\)?format=raw".*/\1/g' \
54 |sort -u |while read A
55do
56 B="`echo $A |$TR / _`"
57 $WGET $WGET_OPTS "$SERVER/$PROJECT/attachment/wiki/$A?format=raw" -O "$OUTDIR"/$B
58 for C in "${OUTDIR}"/*.html
59 do
60 $SED -e 's#\/'$PROJECT'\/attachment\/wiki\/'$A'?format=raw#'$B'#g' -i "$C"
61 done
62done
63
64for A in "${OUTDIR}"/*.html
65do
66 $SED -e 's#href="/'$PROJECT'/wiki/\([^"]*\)"#href="\1.html"#g' \
67 -i $A
68done
69
70rm "$OUTDIR"/*.tmp
71exit 0
diff --git a/doc/nonpersistent/export-wiki.xsl b/doc/nonpersistent/export-wiki.xsl
new file mode 100644
index 0000000..30a600e
--- /dev/null
+++ b/doc/nonpersistent/export-wiki.xsl
@@ -0,0 +1,58 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<xsl:stylesheet version="1.0"
3xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4xmlns="http://www.w3.org/1999/xhtml"
5xmlns:html="http://www.w3.org/1999/xhtml">
6 <xsl:output method="html" indent="yes"/>
7
8 <xsl:template match="/">
9 <xsl:apply-templates />
10 </xsl:template>
11
12 <xsl:template match="/html:html">
13 <html>
14 <head>
15 <title><xsl:value-of select="/html:html/html:head/html:title" /></title>
16 <style type="text/css">
17 @import url(trac.css);
18 </style>
19 </head>
20 <body>
21 <xsl:apply-templates select="//html:div[@class='wiki']" />
22 <div class="footer">
23 <hr />
24 <p><a href="index.html">Back to Index</a></p>
25 </div>
26 </body>
27 </html>
28 </xsl:template>
29
30 <xsl:template match="/pages">
31 <html>
32 <head>
33 <title>Wiki Index</title>
34 <style type="text/css">
35 @import url(trac.css);
36 </style>
37 </head>
38 <body>
39 <h1>Index of Wiki Pages</h1>
40 <ul>
41 <xsl:apply-templates select="page" />
42 </ul>
43 </body>
44 </html>
45 </xsl:template>
46
47 <xsl:template match="page">
48 <li><a href="{.}.html"><xsl:value-of select="." /></a></li>
49 </xsl:template>
50
51 <xsl:template match="node()|@*" priority="-1">
52 <xsl:copy>
53 <xsl:apply-templates select="@*|node()"/>
54 </xsl:copy>
55 </xsl:template>
56
57</xsl:stylesheet>
58
diff --git a/doc/nonpersistent/svn2cl.xsl b/doc/nonpersistent/svn2cl.xsl
new file mode 100755
index 0000000..3672035
--- /dev/null
+++ b/doc/nonpersistent/svn2cl.xsl
@@ -0,0 +1,295 @@
1<?xml version="1.0" encoding="utf-8"?>
2
3<!--
4
5 svn2cl.xsl - xslt stylesheet for converting svn log to a normal
6 changelog
7
8 Usage (replace ++ with two minus signs):
9 svn ++verbose ++xml log | \
10 xsltproc ++stringparam strip-prefix `basename $(pwd)` \
11 ++stringparam linelen 75 \
12 ++stringparam groupbyday yes \
13 ++stringparam include-rev yes \
14 svn2cl.xsl - > ChangeLog
15
16 This file is based on several implementations of this conversion
17 that I was not completely happy with and some other common
18 xslt constructs found on the web.
19
20 Copyright (C) 2004, 2005 Arthur de Jong.
21
22 Redistribution and use in source and binary forms, with or without
23 modification, are permitted provided that the following conditions
24 are met:
25 1. Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 2. Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 3. The name of the author may not be used to endorse or promote
32 products derived from this software without specific prior
33 written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
36 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
39 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
43 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
44 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
45 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46
47-->
48
49<!DOCTYPE page [
50 <!ENTITY tab "&#9;">
51 <!ENTITY newl "&#13;">
52 <!ENTITY space "&#32;">
53]>
54
55<!--
56 TODO
57 - make external lookups of author names possible
58 - find a place for revision numbers
59 - mark deleted files as such
60 - combine paths
61 - make path formatting nicer
62-->
63
64<xsl:stylesheet
65 version="1.0"
66 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
67 xmlns="http://www.w3.org/1999/xhtml">
68
69 <xsl:output
70 method="text"
71 encoding="iso-8859-15"
72 media-type="text/plain"
73 omit-xml-declaration="yes"
74 standalone="yes"
75 indent="no" />
76
77 <xsl:strip-space elements="*" />
78
79 <!-- the prefix of pathnames to strip -->
80 <xsl:param name="strip-prefix" select="'/'" />
81
82 <!-- the length of a line to wrap messages at -->
83 <xsl:param name="linelen" select="75" />
84
85 <!-- whether entries should be grouped by day -->
86 <xsl:param name="groupbyday" select="'no'" />
87
88 <!-- whether entries should be grouped by day -->
89 <xsl:param name="include-rev" select="'no'" />
90
91 <!-- add newlines at the end of the changelog -->
92 <xsl:template match="log">
93 <xsl:apply-templates/>
94 <xsl:text>&newl;</xsl:text>
95 </xsl:template>
96
97 <!-- format one entry from the log -->
98 <xsl:template match="logentry">
99 <!-- save log entry number -->
100 <xsl:variable name="pos" select="position()"/>
101 <!-- fetch previous entry's date -->
102 <xsl:variable name="prevdate">
103 <xsl:apply-templates select="../logentry[position()=(($pos)-1)]/date"/>
104 </xsl:variable>
105 <!-- fetch previous entry's author -->
106 <xsl:variable name="prevauthor">
107 <xsl:apply-templates select="../logentry[position()=(($pos)-1)]/author"/>
108 </xsl:variable>
109 <!-- fetch this entry's date -->
110 <xsl:variable name="date">
111 <xsl:apply-templates select="date" />
112 </xsl:variable>
113 <!-- fetch this entry's author -->
114 <xsl:variable name="author">
115 <xsl:apply-templates select="author" />
116 </xsl:variable>
117 <!-- check if header is changed -->
118 <xsl:if test="($prevdate!=$date) or ($prevauthor!=$author)">
119 <!-- add newline -->
120 <xsl:if test="not(position()=1)">
121 <xsl:text>&newl;</xsl:text>
122 </xsl:if>
123 <!-- date -->
124 <xsl:apply-templates select="date" />
125 <!-- two spaces -->
126 <xsl:text>&space;&space;</xsl:text>
127 <!-- author's name -->
128 <xsl:apply-templates select="author" />
129 <!-- two newlines -->
130 <xsl:text>&newl;&newl;</xsl:text>
131 </xsl:if>
132 <!-- get paths string -->
133 <xsl:variable name="paths">
134 <xsl:apply-templates select="paths" />
135 </xsl:variable>
136 <!-- get revision number -->
137 <xsl:variable name="rev">
138 <xsl:if test="$include-rev='yes'">
139 <xsl:text>[r</xsl:text>
140 <xsl:value-of select="@revision"/>
141 <xsl:text>]&space;</xsl:text>
142 </xsl:if>
143 </xsl:variable>
144 <!-- first line is indented (other indents are done in wrap template) -->
145 <xsl:text>&tab;*&space;</xsl:text>
146 <!-- print the paths and message nicely wrapped -->
147 <xsl:call-template name="wrap">
148 <xsl:with-param name="txt" select="concat($rev,$paths,normalize-space(msg))" />
149 </xsl:call-template>
150 </xsl:template>
151
152 <!-- format date -->
153 <xsl:template match="date">
154 <xsl:variable name="date" select="normalize-space(.)" />
155 <!-- output date part -->
156 <xsl:value-of select="substring($date,1,10)" />
157 <!-- output time part -->
158 <xsl:if test="$groupbyday!='yes'">
159 <xsl:text>&space;</xsl:text>
160 <xsl:value-of select="substring($date,12,5)" />
161 </xsl:if>
162 </xsl:template>
163
164 <!-- format author -->
165 <xsl:template match="author">
166 <xsl:value-of select="normalize-space(.)" />
167 </xsl:template>
168
169 <!-- present a list of paths names -->
170 <xsl:template match="paths">
171 <xsl:for-each select="path">
172 <xsl:sort select="normalize-space(.)" data-type="text" />
173 <!-- unless we are the first entry, add a comma -->
174 <xsl:if test="not(position()=1)">
175 <xsl:text>,&space;</xsl:text>
176 </xsl:if>
177 <!-- print the path name -->
178 <xsl:apply-templates select="."/>
179 </xsl:for-each>
180 <!-- end the list with a colon -->
181 <xsl:text>:&space;</xsl:text>
182 </xsl:template>
183
184 <!-- transform path to something printable -->
185 <xsl:template match="path">
186 <!-- fetch the pathname -->
187 <xsl:variable name="p1" select="normalize-space(.)" />
188 <!-- strip leading slash -->
189 <xsl:variable name="p2">
190 <xsl:choose>
191 <xsl:when test="starts-with($p1,'/')">
192 <xsl:value-of select="substring($p1,2)" />
193 </xsl:when>
194 <xsl:otherwise>
195 <xsl:value-of select="$p1" />
196 </xsl:otherwise>
197 </xsl:choose>
198 </xsl:variable>
199 <!-- strip trailing slash from strip-prefix -->
200 <xsl:variable name="sp">
201 <xsl:choose>
202 <xsl:when test="substring($strip-prefix,string-length($strip-prefix),1)='/'">
203 <xsl:value-of select="substring($strip-prefix,1,string-length($strip-prefix)-1)" />
204 </xsl:when>
205 <xsl:otherwise>
206 <xsl:value-of select="$strip-prefix" />
207 </xsl:otherwise>
208 </xsl:choose>
209 </xsl:variable>
210 <!-- strip strip-prefix -->
211 <xsl:variable name="p3">
212 <xsl:choose>
213 <xsl:when test="starts-with($p2,$sp)">
214 <xsl:value-of select="substring($p2,1+string-length($sp))" />
215 </xsl:when>
216 <xsl:otherwise>
217 <!-- TODO: do not print strings that do not begin with strip-prefix -->
218 <xsl:value-of select="$p2" />
219 </xsl:otherwise>
220 </xsl:choose>
221 </xsl:variable>
222 <!-- strip another slash -->
223 <xsl:variable name="p4">
224 <xsl:choose>
225 <xsl:when test="starts-with($p3,'/')">
226 <xsl:value-of select="substring($p3,2)" />
227 </xsl:when>
228 <xsl:otherwise>
229 <xsl:value-of select="$p3" />
230 </xsl:otherwise>
231 </xsl:choose>
232 </xsl:variable>
233 <!-- translate empty string to dot -->
234 <xsl:choose>
235 <xsl:when test="$p4 = ''">
236 <xsl:text>.</xsl:text>
237 </xsl:when>
238 <xsl:otherwise>
239 <xsl:value-of select="$p4" />
240 </xsl:otherwise>
241 </xsl:choose>
242 </xsl:template>
243
244 <!-- string-wrapping template -->
245 <xsl:template name="wrap">
246 <xsl:param name="txt" />
247 <xsl:choose>
248 <xsl:when test="(string-length($txt) &lt; (($linelen)-9)) or not(contains($txt,' '))">
249 <!-- this is easy, nothing to do -->
250 <xsl:value-of select="$txt" />
251 <!-- add newline -->
252 <xsl:text>&newl;</xsl:text>
253 </xsl:when>
254 <xsl:otherwise>
255 <!-- find the first line -->
256 <xsl:variable name="tmp" select="substring($txt,1,(($linelen)-10))" />
257 <xsl:variable name="line">
258 <xsl:choose>
259 <xsl:when test="contains($tmp,' ')">
260 <xsl:call-template name="find-line">
261 <xsl:with-param name="txt" select="$tmp" />
262 </xsl:call-template>
263 </xsl:when>
264 <xsl:otherwise>
265 <xsl:value-of select="substring-before($txt,' ')" />
266 </xsl:otherwise>
267 </xsl:choose>
268 </xsl:variable>
269 <!-- print newline and tab -->
270 <xsl:value-of select="$line" />
271 <xsl:text>&newl;&tab;&space;&space;</xsl:text>
272 <!-- wrap the rest of the text -->
273 <xsl:call-template name="wrap">
274 <xsl:with-param name="txt" select="normalize-space(substring($txt,string-length($line)+1))" />
275 </xsl:call-template>
276 </xsl:otherwise>
277 </xsl:choose>
278 </xsl:template>
279
280 <!-- template to trim line to contain space as last char -->
281 <xsl:template name="find-line">
282 <xsl:param name="txt" />
283 <xsl:choose>
284 <xsl:when test="substring($txt,string-length($txt),1) = ' '">
285 <xsl:value-of select="normalize-space($txt)" />
286 </xsl:when>
287 <xsl:otherwise>
288 <xsl:call-template name="find-line">
289 <xsl:with-param name="txt" select="substring($txt,1,string-length($txt)-1)" />
290 </xsl:call-template>
291 </xsl:otherwise>
292 </xsl:choose>
293 </xsl:template>
294
295</xsl:stylesheet>
diff --git a/examples/README b/examples/README
new file mode 100644
index 0000000..6db711e
--- /dev/null
+++ b/examples/README
@@ -0,0 +1,25 @@
1Libp11 example code
2===================
3
4This directory contains some example code how to use libp11.
5Feel free to use this code in any way, it is public domain,
6not copyrighted.
7
8auth.c Example for authentication, i.e. get the first
9 token, get the first certificate, ask for pin,
10 login, sign some random data, and verify the
11 signature using the certificate/public key.
12
13For easy building see the Makefile in this directory. If you
14are using autoconf/automake/libtool, you might want to add
15to your configure.ac file:
16
17PKG_CHECK_MODULES([LIBP11], [libp11])
18
19and to your Makefile.am:
20
21bin_PROGRAMS = myapp
22
23myapp_CFLAGS = @LIBP11_CFLAGS@
24myapp_LIBADD = @LIBP11_LIBS@
25myapp_SOURCES = myapp.c
diff --git a/examples/auth.c b/examples/auth.c
new file mode 100644
index 0000000..98ff161
--- /dev/null
+++ b/examples/auth.c
@@ -0,0 +1,225 @@
1/* libp11 example code: auth.c
2 *
3 * This examply simply connects to your smart card
4 * and does a public key authentication.
5 *
6 * Feel free to copy all of the code as needed.
7 *
8 */
9
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <fcntl.h>
13#include <termios.h>
14#include <stdio.h>
15#include <unistd.h>
16#include <string.h>
17#include <libp11.h>
18
19#define RANDOM_SOURCE "/dev/urandom"
20#define RANDOM_SIZE 20
21#define MAX_SIGSIZE 256
22
23int main(int argc, char *argv[])
24{
25 PKCS11_CTX *ctx;
26 PKCS11_SLOT *slots, *slot;
27 PKCS11_CERT *certs;
28
29 PKCS11_KEY *authkey;
30 PKCS11_CERT *authcert;
31 EVP_PKEY *pubkey = NULL;
32
33 unsigned char *random = NULL, *signature = NULL;
34
35 char password[20];
36 int rc = 0, fd;
37 unsigned int nslots, ncerts, siglen;
38
39 if (argc != 2) {
40 fprintf(stderr, "usage: auth /usr/lib/opensc-pkcs11.so\n");
41 return 1;
42 }
43
44 ctx = PKCS11_CTX_new();
45
46 /* load pkcs #11 module */
47 rc = PKCS11_CTX_load(ctx, argv[1]);
48 if (rc) {
49 fprintf(stderr, "loading pkcs11 engine failed: %s\n",
50 ERR_reason_error_string(ERR_get_error()));
51 rc = 1;
52 goto nolib;
53 }
54
55 /* get information on all slots */
56 rc = PKCS11_enumerate_slots(ctx, &slots, &nslots);
57 if (rc < 0) {
58 fprintf(stderr, "no slots available\n");
59 rc = 2;
60 goto noslots;
61 }
62
63 /* get first slot with a token */
64 slot = PKCS11_find_token(ctx, slots, nslots);
65 if (!slot || !slot->token) {
66 fprintf(stderr, "no token available\n");
67 rc = 3;
68 goto notoken;
69 }
70 printf("Slot manufacturer......: %s\n", slot->manufacturer);
71 printf("Slot description.......: %s\n", slot->description);
72 printf("Slot token label.......: %s\n", slot->token->label);
73 printf("Slot token manufacturer: %s\n", slot->token->manufacturer);
74 printf("Slot token model.......: %s\n", slot->token->model);
75 printf("Slot token serialnr....: %s\n", slot->token->serialnr);
76
77 /* get all certs */
78 rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts);
79 if (rc) {
80 fprintf(stderr, "PKCS11_enumerate_certs failed\n");
81 goto failed;
82 }
83 if (ncerts <= 0) {
84 fprintf(stderr, "no certificates found\n");
85 goto failed;
86 }
87
88 /* use the first cert */
89 authcert=&certs[0];
90
91 if (!slot->token->loginRequired)
92 goto loggedin;
93
94 /* get password */
95 struct termios old, new;
96
97 /* Turn echoing off and fail if we can't. */
98 if (tcgetattr(0, &old) != 0)
99 goto failed;
100
101 new = old;
102 new.c_lflag &= ~ECHO;
103 if (tcsetattr(0, TCSAFLUSH, &new) != 0)
104 goto failed;
105
106 /* Read the password. */
107 printf("Password for token %.32s: ", slot->token->label);
108 fgets(password, sizeof(password), stdin);
109
110 /* Restore terminal. */
111 (void)tcsetattr(0, TCSAFLUSH, &old);
112
113 /* strip tailing \n from password */
114 rc = strlen(password);
115 if (rc <= 0)
116 goto failed;
117 password[rc-1]=0;
118
119 /* perform pkcs #11 login */
120 rc = PKCS11_login(slot, 0, password);
121 memset(password, 0, strlen(password));
122 if (rc != 0) {
123 fprintf(stderr, "PKCS11_login failed\n");
124 goto failed;
125 }
126
127 loggedin:
128 /* get random bytes */
129 random = malloc(RANDOM_SIZE);
130 if (!random)
131 goto failed;
132
133 fd = open(RANDOM_SOURCE, O_RDONLY);
134 if (fd < 0) {
135 fprintf(stderr, "fatal: cannot open RANDOM_SOURCE: %s\n",
136 strerror(errno));
137 goto failed;
138 }
139
140 rc = read(fd, random, RANDOM_SIZE);
141 if (rc < 0) {
142 fprintf(stderr, "fatal: read from random source failed: %s\n",
143 strerror(errno));
144 close(fd);
145 goto failed;
146 }
147
148 if (rc < RANDOM_SIZE) {
149 fprintf(stderr, "fatal: read returned less than %d<%d bytes\n",
150 rc, RANDOM_SIZE);
151 close(fd);
152 goto failed;
153 }
154
155 close(fd);
156
157 authkey = PKCS11_find_key(authcert);
158 if (!authkey) {
159 fprintf(stderr, "no key matching certificate available\n");
160 goto failed;
161 }
162
163 /* ask for a sha1 hash of the random data, signed by the key */
164 siglen = MAX_SIGSIZE;
165 signature = malloc(MAX_SIGSIZE);
166 if (!signature)
167 goto failed;
168
169 rc = PKCS11_sign(NID_sha1, random, RANDOM_SIZE, signature, &siglen,
170 authkey);
171 if (rc != 1) {
172 fprintf(stderr, "fatal: pkcs11_sign failed\n");
173 goto failed;
174 }
175
176 /* verify the signature */
177 pubkey = X509_get_pubkey(authcert->x509);
178 if (pubkey == NULL) {
179 fprintf(stderr, "could not extract public key\n");
180 goto failed;
181 }
182
183 /* now verify the result */
184 rc = RSA_verify(NID_sha1, random, RANDOM_SIZE,
185 signature, siglen, pubkey->pkey.rsa);
186 if (rc != 1) {
187 fprintf(stderr, "fatal: RSA_verify failed\n");
188 goto failed;
189 }
190
191 if (pubkey != NULL)
192 EVP_PKEY_free(pubkey);
193
194 if (random != NULL)
195 free(random);
196 if (signature != NULL)
197 free(signature);
198
199 PKCS11_release_all_slots(ctx, slots, nslots);
200 PKCS11_CTX_unload(ctx);
201 PKCS11_CTX_free(ctx);
202
203 CRYPTO_cleanup_all_ex_data();
204 ERR_free_strings();
205 ERR_remove_state(0);
206
207 printf("authentication successfull.\n");
208 return 0;
209
210
211 failed:
212 ERR_print_errors_fp(stderr);
213 notoken:
214 PKCS11_release_all_slots(ctx, slots, nslots);
215
216 noslots:
217 PKCS11_CTX_unload(ctx);
218
219 nolib:
220 PKCS11_CTX_free(ctx);
221
222
223 printf("authentication failed.\n");
224 return 1;
225}
diff --git a/examples/decrypt.c b/examples/decrypt.c
new file mode 100644
index 0000000..16745a4
--- /dev/null
+++ b/examples/decrypt.c
@@ -0,0 +1,240 @@
1/* libp11 example code: auth.c
2 *
3 * This examply simply connects to your smart card
4 * and does a public key authentication.
5 *
6 * Feel free to copy all of the code as needed.
7 *
8 */
9
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <fcntl.h>
13#include <unistd.h>
14#include <termios.h>
15#include <stdio.h>
16#include <string.h>
17#include <libp11.h>
18
19#define RANDOM_SOURCE "/dev/urandom"
20#define RANDOM_SIZE 64
21#define MAX_SIGSIZE 256
22
23int main(int argc, char *argv[])
24{
25 PKCS11_CTX *ctx;
26 PKCS11_SLOT *slots, *slot;
27 PKCS11_CERT *certs;
28
29 PKCS11_KEY *authkey;
30 PKCS11_CERT *authcert;
31 EVP_PKEY *pubkey = NULL;
32
33 unsigned char *random = NULL, *encrypted = NULL, *decrypted = NULL;
34
35 char password[20];
36 int rc = 0, fd, len;
37 unsigned int nslots, ncerts;
38
39 if (argc != 2) {
40 fprintf(stderr, "usage: auth /usr/lib/opensc-pkcs11.so\n");
41 return 1;
42 }
43
44 ctx = PKCS11_CTX_new();
45
46 /* load pkcs #11 module */
47 rc = PKCS11_CTX_load(ctx, argv[1]);
48 if (rc) {
49 fprintf(stderr, "loading pkcs11 engine failed: %s\n",
50 ERR_reason_error_string(ERR_get_error()));
51 rc = 1;
52 goto nolib;
53 }
54
55 /* get information on all slots */
56 rc = PKCS11_enumerate_slots(ctx, &slots, &nslots);
57 if (rc < 0) {
58 fprintf(stderr, "no slots available\n");
59 rc = 2;
60 goto noslots;
61 }
62
63 /* get first slot with a token */
64 slot = PKCS11_find_token(ctx, slots, nslots);
65 if (!slot || !slot->token) {
66 fprintf(stderr, "no token available\n");
67 rc = 3;
68 goto notoken;
69 }
70 printf("Slot manufacturer......: %s\n", slot->manufacturer);
71 printf("Slot description.......: %s\n", slot->description);
72 printf("Slot token label.......: %s\n", slot->token->label);
73 printf("Slot token manufacturer: %s\n", slot->token->manufacturer);
74 printf("Slot token model.......: %s\n", slot->token->model);
75 printf("Slot token serialnr....: %s\n", slot->token->serialnr);
76
77 /* get all certs */
78 rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts);
79 if (rc) {
80 fprintf(stderr, "PKCS11_enumerate_certs failed\n");
81 goto failed;
82 }
83 if (ncerts <= 0) {
84 fprintf(stderr, "no certificates found\n");
85 goto failed;
86 }
87
88 /* use the first cert */
89 authcert=&certs[0];
90
91 /* get random bytes */
92 random = malloc(RANDOM_SIZE);
93 if (!random)
94 goto failed;
95
96 fd = open(RANDOM_SOURCE, O_RDONLY);
97 if (fd < 0) {
98 fprintf(stderr, "fatal: cannot open RANDOM_SOURCE: %s\n",
99 strerror(errno));
100 goto failed;
101 }
102
103 rc = read(fd, random, RANDOM_SIZE);
104 if (rc < 0) {
105 fprintf(stderr, "fatal: read from random source failed: %s\n",
106 strerror(errno));
107 close(fd);
108 goto failed;
109 }
110
111 if (rc < RANDOM_SIZE) {
112 fprintf(stderr, "fatal: read returned less than %d<%d bytes\n",
113 rc, RANDOM_SIZE);
114 close(fd);
115 goto failed;
116 }
117
118 close(fd);
119
120 /* get RSA key */
121 pubkey = X509_get_pubkey(authcert->x509);
122 if (pubkey == NULL) {
123 fprintf(stderr, "could not extract public key\n");
124 goto failed;
125 }
126
127 /* allocate destination buffer */
128 encrypted = malloc(RSA_size(pubkey->pkey.rsa));
129 if (!encrypted) {
130 fprintf(stderr,"out of memory for encrypted data");
131 goto failed;
132 }
133
134 /* use public key for encryption */
135 len = RSA_public_encrypt(RANDOM_SIZE, random, encrypted,
136 pubkey->pkey.rsa, RSA_PKCS1_PADDING);
137 if (len < 0) {
138 fprintf(stderr, "fatal: RSA_public_encrypt failed\n");
139 goto failed;
140 }
141
142 /* now decrypt */
143 if (!slot->token->loginRequired)
144 goto loggedin;
145
146 /* get password */
147 struct termios old, new;
148
149 /* Turn echoing off and fail if we can't. */
150 if (tcgetattr(0, &old) != 0)
151 goto failed;
152
153 new = old;
154 new.c_lflag &= ~ECHO;
155 if (tcsetattr(0, TCSAFLUSH, &new) != 0)
156 goto failed;
157
158 /* Read the password. */
159 printf("Password for token %.32s: ", slot->token->label);
160 fgets(password, sizeof(password), stdin);
161
162 /* Restore terminal. */
163 (void)tcsetattr(0, TCSAFLUSH, &old);
164
165 /* strip tailing \n from password */
166 rc = strlen(password);
167 if (rc <= 0)
168 goto failed;
169 password[rc-1]=0;
170
171 /* perform pkcs #11 login */
172 rc = PKCS11_login(slot, 0, password);
173 memset(password, 0, strlen(password));
174 if (rc != 0) {
175 fprintf(stderr, "PKCS11_login failed\n");
176 goto failed;
177 }
178
179 loggedin:
180
181 authkey = PKCS11_find_key(authcert);
182 if (!authkey) {
183 fprintf(stderr, "no key matching certificate available\n");
184 goto failed;
185 }
186
187 /* allocate space for decrypted data */
188 decrypted = malloc(RSA_size(pubkey->pkey.rsa));
189 if (!decrypted)
190 goto failed;
191
192 rc = PKCS11_private_decrypt(len, encrypted,
193 decrypted, authkey, RSA_PKCS1_PADDING);
194 if (rc != RANDOM_SIZE) {
195 fprintf(stderr, "fatal: PKCS11_private_decrypt failed\n");
196 goto failed;
197 }
198
199 /* check if original matches decypted */
200 if (memcmp(random, decrypted, RANDOM_SIZE) != 0) {
201 fprintf(stderr, "fatal: decrypted data does not match original\n");
202 goto failed;
203 }
204
205 PKCS11_release_all_slots(ctx, slots, nslots);
206 PKCS11_CTX_unload(ctx);
207 PKCS11_CTX_free(ctx);
208
209 if (pubkey != NULL)
210 EVP_PKEY_free(pubkey);
211 if (random != NULL)
212 free(random);
213 if (encrypted != NULL)
214 free(encrypted);
215 if (decrypted != NULL)
216 free(decrypted);
217
218 CRYPTO_cleanup_all_ex_data();
219 ERR_free_strings();
220 ERR_remove_state(0);
221
222 printf("decryption successfull.\n");
223 return 0;
224
225
226 failed:
227 ERR_print_errors_fp(stderr);
228 notoken:
229 PKCS11_release_all_slots(ctx, slots, nslots);
230
231 noslots:
232 PKCS11_CTX_unload(ctx);
233
234 nolib:
235 PKCS11_CTX_free(ctx);
236
237
238 printf("decryption failed.\n");
239 return 1;
240}
diff --git a/examples/getrandom.c b/examples/getrandom.c
new file mode 100644
index 0000000..b8f0a69
--- /dev/null
+++ b/examples/getrandom.c
@@ -0,0 +1,88 @@
1/* libp11 example code: getrandom.c
2 *
3 * This examply simply connects to your smart card and
4 * asks for a few random bytes.
5 *
6 * Feel free to copy all of the code as needed.
7 *
8 */
9
10#include <stdio.h>
11#include <libp11.h>
12
13int main(int argc, char *argv[])
14{
15 PKCS11_CTX *ctx;
16 PKCS11_SLOT *slots, *slot;
17 unsigned char random[10];
18 int rc = 0, i, len;
19 unsigned int nslots;
20
21 if (argc != 2) {
22 fprintf(stderr, "usage: getrandom /usr/lib/opensc-pkcs11.so\n");
23 return 1;
24 }
25
26 /* new context */
27 ctx = PKCS11_CTX_new();
28
29 /* load pkcs #11 module */
30 rc = PKCS11_CTX_load(ctx, argv[1]);
31 if (rc) {
32 fprintf(stderr, "loading pkcs11 engine failed: %s\n",
33 ERR_reason_error_string(ERR_get_error()));
34 rc = 1;
35 goto nolib;
36 }
37
38 /* get information on all slots */
39 rc = PKCS11_enumerate_slots(ctx, &slots, &nslots);
40 if (rc < 0) {
41 fprintf(stderr, "no slots available\n");
42 rc = 2;
43 goto noslots;
44 }
45 printf("%d slots available\n", nslots);
46
47 /* get first slot with a token */
48 slot = PKCS11_find_token(ctx, slots, nslots);
49 if (!slot || !slot->token) {
50 fprintf(stderr, "no token available\n");
51 rc = 3;
52 goto notoken;
53 }
54 printf("Slot manufacturer......: %s\n", slot->manufacturer);
55 printf("Slot description.......: %s\n", slot->description);
56 printf("Slot token label.......: %s\n", slot->token->label);
57 printf("Slot token manufacturer: %s\n", slot->token->manufacturer);
58 printf("Slot token model.......: %s\n", slot->token->model);
59 printf("Slot token serialnr....: %s\n", slot->token->serialnr);
60
61 /* get 10 random bytes */
62 len = sizeof(random);
63 rc = PKCS11_generate_random(slot, random, len);
64 if (rc < 0) {
65 fprintf(stderr, "generate_random failed: %s\n",
66 ERR_reason_error_string(ERR_get_error()));
67 rc = 4;
68 goto norandom;
69 }
70
71 printf("\nRandom numbers generated by the token: ");
72 for (i = 0; i < len; i++)
73 printf("%02X ", random[i]);
74 printf("\n");
75
76 rc = 0;
77
78 norandom:
79 notoken:
80 PKCS11_release_all_slots(ctx, slots, nslots);
81
82 noslots:
83 PKCS11_CTX_unload(ctx);
84
85 nolib:
86 PKCS11_CTX_free(ctx);
87 return rc;
88}
diff --git a/packaged b/packaged
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/packaged
@@ -0,0 +1 @@
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..c66a8cd
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,42 @@
1MAINTAINERCLEANFILES = \
2 $(srcdir)/Makefile.in $(srcdir)/versioninfo.rc
3CLEANFILES = libp11.pc
4EXTRA_DIST = Makefile.mak
5
6noinst_HEADERS= libp11-int.h pkcs11.h
7include_HEADERS= libp11.h
8lib_LTLIBRARIES = libp11.la
9pkgconfig_DATA = libp11.pc
10
11libp11_la_SOURCES = libpkcs11.c p11_attr.c p11_cert.c p11_err.c p11_key.c \
12 p11_load.c p11_misc.c p11_ops.c p11_rsa.c p11_slot.c \
13 libp11.exports
14if WIN32
15libp11_la_SOURCES += versioninfo.rc
16else
17dist_noinst_DATA = versioninfo.rc
18endif
19libp11_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) $(LTLIB_CFLAGS)
20libp11_la_LIBADD = $(OPENSSL_LIBS) $(LTLIB_LIBS)
21libp11_la_LDFLAGS = $(AM_LDFLAGS) \
22 -version-info @LIBP11_LT_CURRENT@:@LIBP11_LT_REVISION@:@LIBP11_LT_AGE@ \
23 -export-symbols "$(srcdir)/libp11.exports" \
24 -no-undefined
25
26if WIN32
27# def file required for MS users to build library
28mylibdir=$(libdir)
29mylib_DATA=.libs/@WIN_LIBPREFIX@p11-@LIBP11_LT_OLDEST@.dll.def
30.libs/@WIN_LIBPREFIX@p11-@LIBP11_LT_OLDEST@.dll.def: libp11.la
31endif
32
33RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
34 $(AM_CPPFLAGS) $(CPPFLAGS)
35LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE)
36
37.rc.lo:
38 $(LTRCCOMPILE) -i "$<" -o "$@"
39
40.rc.o:
41 $(RCCOMPILE) -i "$<" -o "$@"
42
diff --git a/src/Makefile.mak b/src/Makefile.mak
new file mode 100644
index 0000000..73b5428
--- /dev/null
+++ b/src/Makefile.mak
@@ -0,0 +1,33 @@
1LIBLTDL_INC = # E.g. /IC:\libtool-1.5.8-lib\include
2LIBLTDL_LIB = # E.g. C:\libtool-1.5.8-lib\lib\libltdl.lib
3
4OPENSSL_INC = /IC:\openssl\include
5OPENSSL_LIB = C:\openssl\out32dll\libeay32.lib
6
7COPTS = /Zi /MD /nologo /I..\ /I. $(OPENSSL_INC) $(LIBLTDL_INC) /D_WIN32_WINNT=0x0400 /DWIN32 /DWIN32_LEAN_AND_MEAN
8LINKFLAGS = /DEBUG /NOLOGO /INCREMENTAL:NO /MACHINE:IX86
9
10TARGET = libp11.dll
11
12OBJECTS = libpkcs11.obj p11_attr.obj p11_cert.obj p11_err.obj \
13 p11_key.obj p11_load.obj p11_misc.obj p11_rsa.obj p11_slot.obj p11_ops.obj
14
15all: $(TARGET) versioninfo.res
16
17RSC_PROJ=/l 0x809 /r /fo"versioninfo.res"
18
19versioninfo.res: versioninfo.rc
20 rc $(RSC_PROJ) versioninfo.rc
21
22
23.c.obj::
24 cl $(COPTS) /c $<
25
26$(TARGET): $(OBJECTS) versioninfo.res
27 echo LIBRARY $* > $*.def
28 echo EXPORTS >> $*.def
29 type $*.exports >> $*.def
30 link $(LINKFLAGS) /dll /def:$*.def /implib:$*.lib /out:$(TARGET) \
31 $(OBJECTS) $(OPENSSL_LIB) $(LIBLTDL_LIB) versioninfo.res
32 if EXIST $*.dll.manifest mt -manifest $*.dll.manifest -outputresource:$*.dll;2
33
diff --git a/src/libp11-int.h b/src/libp11-int.h
new file mode 100644
index 0000000..be3965f
--- /dev/null
+++ b/src/libp11-int.h
@@ -0,0 +1,159 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#ifndef _LIBP11_INT_H
20#define _LIBP11_INT_H
21
22#include <openssl/bio.h>
23#include <openssl/err.h>
24#include <openssl/x509.h>
25
26#define CRYPTOKI_EXPORTS
27#include <pkcs11.h>
28
29extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR);
30extern CK_RV C_UnloadModule(void *module);
31
32#include "libp11.h"
33
34/* get private implementations of PKCS11 structures */
35
36/*
37 * PKCS11_CTX: context for a PKCS11 implementation
38 */
39typedef struct pkcs11_ctx_private {
40 char *name;
41 void *libinfo;
42 CK_FUNCTION_LIST_PTR method;
43
44 CK_SESSION_HANDLE session;
45 char *init_args;
46} PKCS11_CTX_private;
47#define PRIVCTX(ctx) ((PKCS11_CTX_private *) (ctx->_private))
48
49typedef struct pkcs11_slot_private {
50 PKCS11_CTX *parent;
51 unsigned char haveSession, loggedIn;
52 CK_SLOT_ID id;
53 CK_SESSION_HANDLE session;
54} PKCS11_SLOT_private;
55#define PRIVSLOT(slot) ((PKCS11_SLOT_private *) (slot->_private))
56#define SLOT2CTX(slot) (PRIVSLOT(slot)->parent)
57
58typedef struct pkcs11_token_private {
59 PKCS11_SLOT *parent;
60 int nkeys, nprkeys;
61 PKCS11_KEY *keys;
62 int ncerts;
63 PKCS11_CERT *certs;
64} PKCS11_TOKEN_private;
65#define PRIVTOKEN(token) ((PKCS11_TOKEN_private *) (token->_private))
66#define TOKEN2SLOT(token) (PRIVTOKEN(token)->parent)
67#define TOKEN2CTX(token) SLOT2CTX(TOKEN2SLOT(token))
68
69typedef struct pkcs11_key_ops {
70 int type; /* EVP_PKEY_xxx */
71 int (*get_public) (PKCS11_KEY *, EVP_PKEY *);
72 int (*get_private) (PKCS11_KEY *, EVP_PKEY *);
73} PKCS11_KEY_ops;
74
75typedef struct pkcs11_key_private {
76 PKCS11_TOKEN *parent;
77 CK_OBJECT_HANDLE object;
78 unsigned char id[255];
79 size_t id_len;
80 PKCS11_KEY_ops *ops;
81} PKCS11_KEY_private;
82#define PRIVKEY(key) ((PKCS11_KEY_private *) key->_private)
83#define KEY2SLOT(key) TOKEN2SLOT(KEY2TOKEN(key))
84#define KEY2TOKEN(key) (PRIVKEY(key)->parent)
85#define KEY2CTX(key) TOKEN2CTX(KEY2TOKEN(key))
86
87typedef struct pkcs11_cert_private {
88 PKCS11_TOKEN *parent;
89 CK_OBJECT_HANDLE object;
90 unsigned char id[255];
91 size_t id_len;
92} PKCS11_CERT_private;
93#define PRIVCERT(cert) ((PKCS11_CERT_private *) cert->_private)
94#define CERT2SLOT(cert) TOKEN2SLOT(CERT2TOKEN(cert))
95#define CERT2TOKEN(cert) (PRIVCERT(cert)->parent)
96#define CERT2CTX(cert) TOKEN2CTX(CERT2TOKEN(cert))
97
98/*
99 * Mapping Cryptoki error codes to those used internally
100 * by this code.
101 * Right now, we just map them directly, and make sure
102 * that the few genuine messages we use don't clash with
103 * PKCS#11
104 */
105#define pkcs11_map_err(rv) (rv)
106
107/*
108 * Internal functions
109 */
110#define CRYPTOKI_checkerr(f, rv) \
111 do { if (rv) { \
112 PKCS11err(f, pkcs11_map_err(rv)); \
113 return -1; \
114 } } while (0)
115#define CRYPTOKI_call(ctx, func_and_args) \
116 PRIVCTX(ctx)->method->func_and_args
117
118/* Memory allocation */
119#define PKCS11_NEW(type) \
120 ((type *) pkcs11_malloc(sizeof(type)))
121#define PKCS11_DUP(s) \
122 pkcs11_strdup((char *) s, sizeof(s))
123
124extern void pkcs11_release_slot(PKCS11_CTX *, PKCS11_SLOT *slot);
125
126extern void pkcs11_destroy_keys(PKCS11_TOKEN *);
127extern void pkcs11_destroy_certs(PKCS11_TOKEN *);
128extern void *pkcs11_malloc(size_t);
129extern char *pkcs11_strdup(char *, size_t);
130
131extern int pkcs11_getattr(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
132 unsigned int, void *, size_t);
133extern int pkcs11_getattr_s(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
134 unsigned int, void *, size_t);
135extern int pkcs11_getattr_var(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
136 unsigned int, void *, size_t *);
137extern int pkcs11_getattr_bn(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
138 unsigned int, BIGNUM **);
139
140#define key_getattr(key, t, p, s) \
141 pkcs11_getattr(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s))
142
143#define key_getattr_bn(key, t, bn) \
144 pkcs11_getattr_bn(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (bn))
145
146typedef int (*pkcs11_i2d_fn) (void *, unsigned char **);
147extern void pkcs11_addattr(CK_ATTRIBUTE_PTR, int, const void *, size_t);
148extern void pkcs11_addattr_int(CK_ATTRIBUTE_PTR, int, unsigned long);
149extern void pkcs11_addattr_bool(CK_ATTRIBUTE_PTR, int, int);
150extern void pkcs11_addattr_s(CK_ATTRIBUTE_PTR, int, const char *);
151extern void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR, int, const BIGNUM *);
152extern void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR, int, pkcs11_i2d_fn, void *);
153extern void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR, unsigned int);
154
155extern void *memdup(const void *, size_t);
156
157extern PKCS11_KEY_ops pkcs11_rsa_ops;
158
159#endif
diff --git a/src/libp11.exports b/src/libp11.exports
new file mode 100644
index 0000000..aecbdba
--- /dev/null
+++ b/src/libp11.exports
@@ -0,0 +1,37 @@
1PKCS11_CTX_init_args
2PKCS11_CTX_new
3PKCS11_CTX_load
4PKCS11_CTX_unload
5PKCS11_CTX_free
6PKCS11_open_session
7PKCS11_enumerate_slots
8PKCS11_release_all_slots
9PKCS11_find_token
10PKCS11_login
11PKCS11_logout
12PKCS11_enumerate_keys
13PKCS11_get_key_type
14PKCS11_get_key_size
15PKCS11_get_key_modulus
16PKCS11_get_key_exponent
17PKCS11_get_private_key
18PKCS11_get_public_key
19PKCS11_get_slotid_from_slot
20PKCS11_find_certificate
21PKCS11_find_key
22PKCS11_enumerate_certs
23PKCS11_init_token
24PKCS11_init_pin
25PKCS11_change_pin
26PKCS11_generate_key
27PKCS11_store_private_key
28PKCS11_store_public_key
29PKCS11_store_certificate
30PKCS11_sign
31PKCS11_private_encrypt
32PKCS11_private_decrypt
33PKCS11_verify
34PKCS11_seed_random
35PKCS11_generate_random
36PKCS11_get_rsa_method
37ERR_load_PKCS11_strings
diff --git a/src/libp11.h b/src/libp11.h
new file mode 100644
index 0000000..89604ff
--- /dev/null
+++ b/src/libp11.h
@@ -0,0 +1,428 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19/**
20 * @file libp11.h
21 * @brief libp11 header file
22 */
23
24#ifndef _LIB11_H
25#define _LIB11_H
26
27#include <openssl/bio.h>
28#include <openssl/err.h>
29#include <openssl/x509.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35/* get some structures for local code to handle pkcs11 data readily */
36#define ERR_LIB_PKCS11 ERR_LIB_USER
37
38#define PKCS11err(f,r) \
39ERR_PUT_error(ERR_LIB_PKCS11,(f),(r),__FILE__,__LINE__)
40
41/*
42 * The purpose of this library is to provide a simple PKCS11
43 * interface to OpenSSL application that wish to use a previously
44 * initialized card (as opposed to initializing it, etc).
45 *
46 * I am therefore making some simplifying assumptions:
47 *
48 * - no support for any operations that alter the card,
49 * i.e. readonly-login
50 */
51
52/** PKCS11 key object (public or private) */
53typedef struct PKCS11_key_st {
54 char *label;
55 unsigned char *id;
56 size_t id_len;
57 unsigned char isPrivate; /**< private key present? */
58 unsigned char needLogin; /**< login to read private key? */
59 EVP_PKEY *evp_key; /**< initially NULL, need to call PKCS11_load_key */
60 void *_private;
61} PKCS11_KEY;
62
63/** PKCS11 certificate object */
64typedef struct PKCS11_cert_st {
65 char *label;
66 unsigned char *id;
67 size_t id_len;
68 X509 *x509;
69 void *_private;
70} PKCS11_CERT;
71
72/** PKCS11 token: smart card or USB key */
73typedef struct PKCS11_token_st {
74 char *label;
75 char *manufacturer;
76 char *model;
77 char *serialnr;
78 unsigned char initialized;
79 unsigned char loginRequired;
80 unsigned char secureLogin;
81 unsigned char userPinSet;
82 unsigned char readOnly;
83 unsigned char hasRng;
84 unsigned char userPinCountLow;
85 unsigned char userPinFinalTry;
86 unsigned char userPinLocked;
87 unsigned char userPinToBeChanged;
88 unsigned char soPinCountLow;
89 unsigned char soPinFinalTry;
90 unsigned char soPinLocked;
91 unsigned char soPinToBeChanged;
92 void *_private;
93} PKCS11_TOKEN;
94
95/** PKCS11 slot: card reader */
96typedef struct PKCS11_slot_st {
97 char *manufacturer;
98 char *description;
99 unsigned char removable;
100 PKCS11_TOKEN *token; /**< NULL if no token present */
101 void *_private;
102} PKCS11_SLOT;
103
104/** PKCS11 context */
105typedef struct PKCS11_ctx_st {
106 char *manufacturer;
107 char *description;
108 void *_private;
109} PKCS11_CTX;
110
111/**
112 * Create a new libp11 context
113 *
114 * This should be the first function called in the use of libp11
115 * @return an allocated context
116 */
117extern PKCS11_CTX *PKCS11_CTX_new(void);
118
119/**
120 * Specify any private PKCS#11 module initializtion args, if necessary
121 *
122 * @return none
123 */
124extern void PKCS11_CTX_init_args(PKCS11_CTX * ctx, const char * init_args);
125
126/**
127 * Load a PKCS#11 module
128 *
129 * @param ctx context allocated by PKCS11_CTX_new()
130 * @param ident PKCS#11 library filename
131 * @retval 0 success
132 * @retval -1 error
133 */
134extern int PKCS11_CTX_load(PKCS11_CTX * ctx, const char * ident);
135
136/**
137 * Unload a PKCS#11 module
138 *
139 * @param ctx context allocated by PKCS11_CTX_new()
140 */
141extern void PKCS11_CTX_unload(PKCS11_CTX * ctx);
142
143/**
144 * Free a libp11 context
145 *
146 * @param ctx context allocated by PKCS11_CTX_new()
147 */
148extern void PKCS11_CTX_free(PKCS11_CTX * ctx);
149
150/** Open a session in RO or RW mode
151 *
152 * @param slot slot descriptor returned by PKCS11_find_token() or PKCS11_enumerate_slots()
153 * @param rw open in read/write mode is mode != 0, otherwise in read only mode
154 * @retval 0 success
155 * @retval -1 error
156 */
157extern int PKCS11_open_session(PKCS11_SLOT * slot, int rw);
158
159/**
160 * Get a list of all slots
161 *
162 * @param ctx context allocated by PKCS11_CTX_new()
163 * @param slotsp pointer on a list of slots
164 * @param nslotsp size of the allocated list
165 * @retval 0 success
166 * @retval -1 error
167 */
168extern int PKCS11_enumerate_slots(PKCS11_CTX * ctx,
169 PKCS11_SLOT **slotsp, unsigned int *nslotsp);
170
171/**
172 * Get the slot_id from a slot as it is stored in private
173 *
174 * @param slotp pointer on a slot
175 * @retval the slotid
176 */
177extern unsigned long PKCS11_get_slotid_from_slot(PKCS11_SLOT *slotp);
178
179/**
180 * Free the list of slots allocated by PKCS11_enumerate_slots()
181 *
182 * @param ctx context allocated by PKCS11_CTX_new()
183 * @param slots list of slots allocated by PKCS11_enumerate_slots()
184 * @param nslots size of the list
185 */
186extern void PKCS11_release_all_slots(PKCS11_CTX * ctx,
187 PKCS11_SLOT *slots, unsigned int nslots);
188
189/**
190 * Find the first slot with a token
191 *
192 * @param ctx context allocated by PKCS11_CTX_new()
193 * @param slots list of slots allocated by PKCS11_enumerate_slots()
194 * @param nslots size of the list
195 * @retval !=NULL pointer on a slot structure
196 * @retval NULL error
197 */
198PKCS11_SLOT *PKCS11_find_token(PKCS11_CTX * ctx,
199 PKCS11_SLOT *slots, unsigned int nslots);
200
201/**
202 * Authenticate to the card
203 *
204 * @param slot slot returned by PKCS11_find_token()
205 * @param so login as CKU_SO if != 0, otherwise login as CKU_USER
206 * @param pin PIN value
207 * @retval 0 success
208 * @retval -1 error
209 */
210extern int PKCS11_login(PKCS11_SLOT * slot, int so, const char *pin);
211
212/**
213 * De-authenticate from the card
214 *
215 * @param slot slot returned by PKCS11_find_token()
216 * @retval 0 success
217 * @retval -1 error
218 */
219extern int PKCS11_logout(PKCS11_SLOT * slot);
220
221/* Get a list of all keys associated with this token */
222extern int PKCS11_enumerate_keys(PKCS11_TOKEN *, PKCS11_KEY **, unsigned int *);
223
224/* Get the key type (as EVP_PKEY_XXX) */
225extern int PKCS11_get_key_type(PKCS11_KEY *);
226
227/* Get size of key modulus in number of bytes */
228extern int PKCS11_get_key_size(const PKCS11_KEY *);
229/* Get actual modules and public exponent as BIGNUM */
230extern int PKCS11_get_key_modulus(PKCS11_KEY *, BIGNUM **);
231extern int PKCS11_get_key_exponent(PKCS11_KEY *, BIGNUM **);
232
233/* Get the enveloped private key */
234/**
235 * Returns a EVP_PKEY object for the private key
236 *
237 * @param key PKCS11_KEY object
238 * @retval !=NULL reference to EVP_PKEY object.
239 * The returned EVP_PKEY object should be treated as const
240 * and must not be freed.
241 * @retval NULL error
242 */
243extern EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY *key);
244/**
245 * Returns a EVP_PKEY object with the public key
246 *
247 * @param key PKCS11_KEY object
248 * @retval !=NULL reference to EVP_PKEY object.
249 * The returned EVP_PKEY object should be treated as const
250 * and must not be freed.
251 * @retval NULL error
252 */
253extern EVP_PKEY *PKCS11_get_public_key(PKCS11_KEY *key);
254
255/* Find the corresponding certificate (if any) */
256extern PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY *);
257
258/* Find the corresponding key (if any) */
259extern PKCS11_KEY *PKCS11_find_key(PKCS11_CERT *);
260
261/* Get a list of all certificates associated with this token */
262extern int PKCS11_enumerate_certs(PKCS11_TOKEN *, PKCS11_CERT **, unsigned int *);
263
264/**
265 * Initialize a token
266 *
267 * @param token token descriptor (in general slot->token)
268 * @param pin Security Officer PIN value
269 * @param label new name of the token
270 * @retval 0 success
271 * @retval -1 error
272 */
273extern int PKCS11_init_token(PKCS11_TOKEN * token, const char *pin,
274 const char *label);
275
276/**
277 * Initialize the user PIN on a token
278 *
279 * @param token token descriptor (in general slot->token)
280 * @param pin new user PIN value
281 * @retval 0 success
282 * @retval -1 error
283 */
284extern int PKCS11_init_pin(PKCS11_TOKEN * token, const char *pin);
285
286/**
287 * Change the user PIN on a token
288 *
289 * @param slot slot returned by PKCS11_find_token()
290 * @param old_pin old PIN value
291 * @param new_pin new PIN value
292 * @retval 0 success
293 * @retval -1 error
294 */
295extern int PKCS11_change_pin(PKCS11_SLOT * slot, const char *old_pin,
296 const char *new_pin);
297
298/**
299 * Generate and store a private key on the token
300 *
301 * @param token token returned by PKCS11_find_token()
302 * @param algorithm EVP_PKEY_RSA
303 * @param bits size of the modulus in bits
304 * @param label label for this key
305 * @param id bytes to use as id value
306 * @param id_len length of id value.
307 * @retval 0 success
308 * @retval -1 error
309 */
310
311extern int PKCS11_generate_key(PKCS11_TOKEN * token, int algorithm, unsigned int bits, char *label, unsigned char* id, size_t id_len);
312
313/**
314 * Store private key on a token
315 *
316 * @param token token returned by PKCS11_find_token()
317 * @param pk private key
318 * @param label label for this key
319 * @param id bytes to use as id value
320 * @param id_len length of id value.
321 * @retval 0 success
322 * @retval -1 error
323 */
324extern int PKCS11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len);
325
326/**
327 * Store public key on a token
328 *
329 * @param token token returned by PKCS11_find_token()
330 * @param pk private key
331 * @param label label for this key
332 * @param id bytes to use as id value
333 * @param id_len length of id value.
334 * @retval 0 success
335 * @retval -1 error
336 */
337extern int PKCS11_store_public_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len);
338
339/**
340 * Store certificate on a token
341 *
342 * @param token token returned by PKCS11_find_token()
343 * @param x509 x509 certificate object
344 * @param label label for this certificate
345 * @param id bytes to use as id value
346 * @param id_len length of id value.
347 * @param ret_cert put new PKCS11_CERT object here
348 * @retval 0 success
349 * @retval -1 error
350 */
351extern int PKCS11_store_certificate(PKCS11_TOKEN * token, X509 * x509,
352 char *label, unsigned char *id, size_t id_len,
353 PKCS11_CERT **ret_cert);
354
355/* rsa private key operations */
356extern int PKCS11_sign(int type, const unsigned char *m, unsigned int m_len,
357 unsigned char *sigret, unsigned int *siglen, const PKCS11_KEY * key);
358extern int PKCS11_private_encrypt(int flen, const unsigned char *from,
359 unsigned char *to, const PKCS11_KEY * rsa, int padding);
360/**
361 * Decrypts data using the private key
362 *
363 * @param flen length of the encrypted data
364 * @param from encrypted data
365 * @param to output buffer (MUST be a least flen bytes long)
366 * @param key private key object
367 * @param padding padding algorithm to be used
368 * @return the length of the decrypted data or 0 if an error occurred
369 */
370extern int PKCS11_private_decrypt(int flen, const unsigned char *from,
371 unsigned char *to, PKCS11_KEY * key, int padding);
372extern int PKCS11_verify(int type, const unsigned char *m, unsigned int m_len,
373 unsigned char *signature, unsigned int siglen, PKCS11_KEY * key);
374
375/* access random number generator */
376extern int PKCS11_seed_random(PKCS11_SLOT *, const unsigned char *s, unsigned int s_len);
377extern int PKCS11_generate_random(PKCS11_SLOT *, unsigned char *r, unsigned int r_len);
378
379/* using with openssl method mechanism */
380RSA_METHOD *PKCS11_get_rsa_method(void);
381
382/**
383 * Load PKCS11 error strings
384 *
385 * Call this function to be able to use ERR_reason_error_string(ERR_get_error())
386 * to get an textual version of the latest error code
387 */
388extern void ERR_load_PKCS11_strings(void);
389
390/*
391 * Function and reason codes
392 */
393#define PKCS11_F_PKCS11_CTX_LOAD 1
394#define PKCS11_F_PKCS11_ENUM_SLOTS 2
395#define PKCS11_F_PKCS11_CHECK_TOKEN 3
396#define PKCS11_F_PKCS11_OPEN_SESSION 4
397#define PKCS11_F_PKCS11_LOGIN 5
398#define PKCS11_F_PKCS11_ENUM_KEYS 6
399#define PKCS11_F_PKCS11_GET_KEY 7
400#define PKCS11_F_PKCS11_RSA_DECRYPT 8
401#define PKCS11_F_PKCS11_RSA_ENCRYPT 9
402#define PKCS11_F_PKCS11_RSA_SIGN 10
403#define PKCS11_F_PKCS11_RSA_VERIFY 11
404#define PKCS11_F_PKCS11_ENUM_CERTS 12
405#define PKCS11_F_PKCS11_INIT_TOKEN 13
406#define PKCS11_F_PKCS11_INIT_PIN 14
407#define PKCS11_F_PKCS11_LOGOUT 15
408#define PKCS11_F_PKCS11_STORE_PRIVATE_KEY 16
409#define PKCS11_F_PKCS11_GENERATE_KEY 17
410#define PKCS11_F_PKCS11_STORE_PUBLIC_KEY 18
411#define PKCS11_F_PKCS11_STORE_CERTIFICATE 19
412#define PKCS11_F_PKCS11_SEED_RANDOM 20
413#define PKCS11_F_PKCS11_GENERATE_RANDOM 21
414#define PKCS11_F_PKCS11_CHANGE_PIN 22
415#define PKCS11_F_PKCS11_GETATTR 40
416
417#define PKCS11_ERR_BASE 1024
418#define PKCS11_LOAD_MODULE_ERROR (PKCS11_ERR_BASE+1)
419#define PKCS11_MODULE_LOADED_ERROR (PKCS11_ERR_BASE+2)
420#define PKCS11_SYMBOL_NOT_FOUND_ERROR (PKCS11_ERR_BASE+3)
421#define PKCS11_NOT_SUPPORTED (PKCS11_ERR_BASE+4)
422#define PKCS11_NO_SESSION (PKCS11_ERR_BASE+5)
423#define PKCS11_KEYGEN_FAILED (PKCS11_ERR_BASE+6)
424
425#ifdef __cplusplus
426}
427#endif
428#endif
diff --git a/src/libp11.pc.in b/src/libp11.pc.in
new file mode 100644
index 0000000..255b220
--- /dev/null
+++ b/src/libp11.pc.in
@@ -0,0 +1,12 @@
1prefix=@prefix@
2exec_prefix=@exec_prefix@
3libdir=@libdir@
4includedir=@includedir@
5
6Name: libp11
7Description: libp11
8Version: @VERSION@
9Libs: -L${libdir} -lp11
10Libs.private: -lcrypto
11Cflags: -I${includedir}
12
diff --git a/src/libpkcs11.c b/src/libpkcs11.c
new file mode 100644
index 0000000..a146361
--- /dev/null
+++ b/src/libpkcs11.c
@@ -0,0 +1,101 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19/*
20 * Convenience pkcs11 library that can be linked into an application,
21 * and will bind to a specific pkcs11 module.
22 *
23 * Copyright (C) 2002 Olaf Kirch <okir@lst.de>
24 */
25
26#include <config.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30#include <ltdl.h>
31#include "libp11-int.h"
32
33#define MAGIC 0xd00bed00
34
35struct sc_pkcs11_module {
36 unsigned int _magic;
37 lt_dlhandle handle;
38};
39typedef struct sc_pkcs11_module sc_pkcs11_module_t;
40
41/*
42 * Load a module - this will load the shared object, call
43 * C_Initialize, and get the list of function pointers
44 */
45void *
46C_LoadModule(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs)
47{
48 sc_pkcs11_module_t *mod;
49 CK_RV (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
50 int rv;
51
52 if (mspec == NULL)
53 return NULL;
54
55 if (lt_dlinit() != 0)
56 return NULL;
57
58 mod = (sc_pkcs11_module_t *) calloc(1, sizeof(*mod));
59 mod->_magic = MAGIC;
60
61 mod->handle = lt_dlopen(mspec);
62 if (mod->handle == NULL)
63 goto failed;
64
65 /* Get the list of function pointers */
66 c_get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
67 lt_dlsym(mod->handle, "C_GetFunctionList");
68 if (!c_get_function_list)
69 goto failed;
70 rv = c_get_function_list(funcs);
71 if (rv == CKR_OK)
72 return (void *) mod;
73
74failed:
75 C_UnloadModule((void *) mod);
76 return NULL;
77}
78
79/*
80 * Unload a pkcs11 module.
81 * The calling application is responsible for cleaning up
82 * and calling C_Finalize
83 */
84CK_RV
85C_UnloadModule(void *module)
86{
87 sc_pkcs11_module_t *mod = (sc_pkcs11_module_t *) module;
88
89 if (!mod || mod->_magic != MAGIC)
90 return CKR_ARGUMENTS_BAD;
91
92 if (lt_dlclose(mod->handle) < 0)
93 return CKR_FUNCTION_FAILED;
94
95 memset(mod, 0, sizeof(*mod));
96 free(mod);
97
98 lt_dlexit();
99
100 return CKR_OK;
101}
diff --git a/src/p11_attr.c b/src/p11_attr.c
new file mode 100644
index 0000000..83f603b
--- /dev/null
+++ b/src/p11_attr.c
@@ -0,0 +1,156 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19/*
20 * PKCS11 attribute querying.
21 *
22 * The number of layers we stack on top of each other here
23 * is frightening.
24 *
25 * Copyright (C) 2002, Olaf Kirch <okir@lst.de>
26 */
27
28#include <config.h>
29#include <assert.h>
30#include <string.h>
31
32#include "libp11-int.h"
33
34static int pkcs11_getattr_int(PKCS11_CTX *, CK_SESSION_HANDLE,
35 CK_OBJECT_HANDLE, CK_ATTRIBUTE_TYPE, void *, size_t *);
36
37/*
38 * Query pkcs11 attributes
39 */
40static int
41pkcs11_getattr_int(PKCS11_CTX * ctx, CK_SESSION_HANDLE session,
42 CK_OBJECT_HANDLE o, CK_ATTRIBUTE_TYPE type, void *value,
43 size_t * size)
44{
45 CK_ATTRIBUTE templ;
46 int rv;
47
48 templ.type = type;
49 templ.pValue = value;
50 templ.ulValueLen = *size;
51
52 rv = CRYPTOKI_call(ctx, C_GetAttributeValue(session, o, &templ, 1));
53 CRYPTOKI_checkerr(PKCS11_F_PKCS11_GETATTR, rv);
54
55 *size = templ.ulValueLen;
56 return 0;
57}
58
59int
60pkcs11_getattr_var(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object,
61 unsigned int type, void *value, size_t * size)
62{
63 return pkcs11_getattr_int(TOKEN2CTX(token),
64 PRIVSLOT(TOKEN2SLOT(token))->session,
65 object, type, value, size);
66}
67
68int
69pkcs11_getattr(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object,
70 unsigned int type, void *value, size_t size)
71{
72 return pkcs11_getattr_var(token, object, type, value, &size);
73}
74
75int
76pkcs11_getattr_s(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object,
77 unsigned int type, void *value, size_t size)
78{
79 memset(value, 0, size);
80 return pkcs11_getattr_var(token, object, type, value, &size);
81}
82
83int
84pkcs11_getattr_bn(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object,
85 unsigned int type, BIGNUM ** bn)
86{
87 CK_BYTE binary[4196 / 8];
88 size_t size = sizeof(binary);
89
90 if (pkcs11_getattr_var(token, object, type, binary, &size))
91 return -1;
92 if (size == -1) {
93 PKCS11err(PKCS11_F_PKCS11_GETATTR,
94 pkcs11_map_err(CKR_ATTRIBUTE_TYPE_INVALID));
95 return -1;
96 }
97 *bn = BN_bin2bn(binary, size, *bn);
98 return *bn ? 0 : -1;
99}
100
101/*
102 * Add attributes to template
103 */
104void pkcs11_addattr(CK_ATTRIBUTE_PTR ap, int type, const void *data, size_t size)
105{
106 ap->type = type;
107 ap->pValue = malloc(size);
108 memcpy(ap->pValue, data, size);
109 ap->ulValueLen = size;
110}
111
112/* In PKCS11, virtually every integer is a CK_ULONG */
113void pkcs11_addattr_int(CK_ATTRIBUTE_PTR ap, int type, unsigned long value)
114{
115 CK_ULONG ulValue = value;
116
117 pkcs11_addattr(ap, type, &ulValue, sizeof(ulValue));
118}
119
120void pkcs11_addattr_bool(CK_ATTRIBUTE_PTR ap, int type, int value)
121{
122 pkcs11_addattr(ap, type, &value, sizeof(CK_BBOOL));
123}
124
125void pkcs11_addattr_s(CK_ATTRIBUTE_PTR ap, int type, const char *s)
126{
127 pkcs11_addattr(ap, type, s, s ? strlen(s) : 0); // RFC2279 string an unpadded string of CK_UTF8CHARs with no null-termination
128}
129
130void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR ap, int type, const BIGNUM * bn)
131{
132 unsigned char temp[1024];
133 unsigned int n;
134
135 assert(BN_num_bytes(bn) <= sizeof(temp));
136 n = BN_bn2bin(bn, temp);
137 pkcs11_addattr(ap, type, temp, n);
138}
139
140void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR ap, int type, pkcs11_i2d_fn enc, void *obj)
141{
142 unsigned char *p;
143
144 ap->type = type;
145 ap->ulValueLen = enc(obj, NULL);
146 ap->pValue = p = (unsigned char *) malloc(ap->ulValueLen);
147 enc(obj, &p);
148}
149
150void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR ap, unsigned int n)
151{
152 while (n--) {
153 if (ap[n].pValue)
154 free(ap[n].pValue);
155 }
156}
diff --git a/src/p11_cert.c b/src/p11_cert.c
new file mode 100644
index 0000000..157bc6b
--- /dev/null
+++ b/src/p11_cert.c
@@ -0,0 +1,258 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19/*
20 * p11_cert.c - Handle certificates residing on a PKCS11 token
21 *
22 * Copyright (C) 2002, Olaf Kirch <okir@lst.de>
23 */
24
25#include <config.h>
26#include <string.h>
27#include "libp11-int.h"
28
29static int pkcs11_find_certs(PKCS11_TOKEN *);
30static int pkcs11_next_cert(PKCS11_CTX *, PKCS11_TOKEN *, CK_SESSION_HANDLE);
31static int pkcs11_init_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
32 CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o,
33 PKCS11_CERT **);
34
35static CK_OBJECT_CLASS cert_search_class;
36static CK_ATTRIBUTE cert_search_attrs[] = {
37 {CKA_CLASS, &cert_search_class, sizeof(cert_search_class)},
38};
39#define numof(arr) (sizeof(arr)/sizeof((arr)[0]))
40
41/*
42 * Enumerate all certs on the card
43 */
44int
45PKCS11_enumerate_certs(PKCS11_TOKEN * token,
46 PKCS11_CERT ** certp, unsigned int *countp)
47{
48 PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
49
50 if (priv->ncerts < 0) {
51 priv->ncerts = 0;
52 if (pkcs11_find_certs(token)) {
53 pkcs11_destroy_certs(token);
54 return -1;
55 }
56 }
57 *certp = priv->certs;
58 *countp = priv->ncerts;
59 return 0;
60}
61
62/*
63 * Find certificate matching a key
64 */
65PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY * key)
66{
67 PKCS11_KEY_private *kpriv;
68 PKCS11_CERT_private *cpriv;
69 PKCS11_CERT *cert;
70 unsigned int n, count;
71
72 kpriv = PRIVKEY(key);
73 if (PKCS11_enumerate_certs(KEY2TOKEN(key), &cert, &count))
74 return NULL;
75 for (n = 0; n < count; n++, cert++) {
76 cpriv = PRIVCERT(cert);
77 if (cpriv->id_len == kpriv->id_len
78 && !memcmp(cpriv->id, kpriv->id, kpriv->id_len))
79 return cert;
80 }
81 return NULL;
82}
83
84/*
85 * Find all certs of a given type (public or private)
86 */
87static int pkcs11_find_certs(PKCS11_TOKEN * token)
88{
89 PKCS11_SLOT *slot = TOKEN2SLOT(token);
90 PKCS11_CTX *ctx = TOKEN2CTX(token);
91 CK_SESSION_HANDLE session;
92 int rv, res = -1;
93
94 /* Make sure we have a session */
95 if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 0))
96 return -1;
97 session = PRIVSLOT(slot)->session;
98
99 /* Tell the PKCS11 lib to enumerate all matching objects */
100 cert_search_class = CKO_CERTIFICATE;
101 rv = CRYPTOKI_call(ctx, C_FindObjectsInit(session, cert_search_attrs,
102 numof(cert_search_attrs)));
103 CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_CERTS, rv);
104
105 do {
106 res = pkcs11_next_cert(ctx, token, session);
107 } while (res == 0);
108
109 CRYPTOKI_call(ctx, C_FindObjectsFinal(session));
110 return (res < 0) ? -1 : 0;
111}
112
113static int pkcs11_next_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
114 CK_SESSION_HANDLE session)
115{
116 CK_OBJECT_HANDLE obj;
117 CK_ULONG count;
118 int rv;
119
120 /* Get the next matching object */
121 rv = CRYPTOKI_call(ctx, C_FindObjects(session, &obj, 1, &count));
122 CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_CERTS, rv);
123
124 if (count == 0)
125 return 1;
126
127 if (pkcs11_init_cert(ctx, token, session, obj, NULL))
128 return -1;
129
130 return 0;
131}
132
133static int pkcs11_init_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
134 CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret)
135{
136 PKCS11_TOKEN_private *tpriv;
137 PKCS11_CERT_private *kpriv;
138 PKCS11_CERT *cert, *tmp;
139 char label[256], data[2048];
140 unsigned char id[256];
141 CK_CERTIFICATE_TYPE cert_type;
142 size_t size;
143
144 size = sizeof(cert_type);
145 if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, &cert_type, &size))
146 return -1;
147
148 /* Ignore any certs we don't understand */
149 if (cert_type != CKC_X_509)
150 return 0;
151
152 tpriv = PRIVTOKEN(token);
153 tmp = (PKCS11_CERT *) OPENSSL_realloc(tpriv->certs,
154 (tpriv->ncerts + 1) * sizeof(PKCS11_CERT));
155 if (!tmp) {
156 free(tpriv->certs);
157 tpriv->certs = NULL;
158 return -1;
159 }
160 tpriv->certs = tmp;
161
162 cert = tpriv->certs + tpriv->ncerts++;
163 memset(cert, 0, sizeof(*cert));
164 cert->_private = kpriv = PKCS11_NEW(PKCS11_CERT_private);
165 kpriv->object = obj;
166 kpriv->parent = token;
167
168 if (!pkcs11_getattr_s(token, obj, CKA_LABEL, label, sizeof(label)))
169 cert->label = BUF_strdup(label);
170 size = sizeof(data);
171 if (!pkcs11_getattr_var(token, obj, CKA_VALUE, data, &size)) {
172 const unsigned char *p = (unsigned char *) data;
173
174 cert->x509 = d2i_X509(NULL, &p, size);
175 }
176 cert->id_len = sizeof(id);
177 if (!pkcs11_getattr_var(token, obj, CKA_ID, id, &cert->id_len)) {
178 cert->id = (unsigned char *) malloc(cert->id_len);
179 memcpy(cert->id, id, cert->id_len);
180 }
181
182 /* Initialize internal information */
183 kpriv->id_len = sizeof(kpriv->id);
184 if (pkcs11_getattr_var(token, obj, CKA_ID, kpriv->id, &kpriv->id_len))
185 kpriv->id_len = 0;
186
187 if (ret)
188 *ret = cert;
189
190 return 0;
191}
192
193/*
194 * Destroy all certs
195 */
196void pkcs11_destroy_certs(PKCS11_TOKEN * token)
197{
198 PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
199
200 while (priv->ncerts > 0) {
201 PKCS11_CERT *cert = &priv->certs[--(priv->ncerts)];
202
203 if (cert->x509)
204 X509_free(cert->x509);
205 OPENSSL_free(cert->label);
206 if (cert->id)
207 free(cert->id);
208 if (cert->_private != NULL)
209 OPENSSL_free(cert->_private);
210 }
211 if (priv->certs)
212 OPENSSL_free(priv->certs);
213 priv->ncerts = -1;
214 priv->certs = NULL;
215}
216
217/*
218 * Store certificate
219 */
220int
221PKCS11_store_certificate(PKCS11_TOKEN * token, X509 * x509, char *label,
222 unsigned char *id, size_t id_len,
223 PKCS11_CERT ** ret_cert)
224{
225 PKCS11_SLOT *slot = TOKEN2SLOT(token);
226 PKCS11_CTX *ctx = TOKEN2CTX(token);
227 CK_SESSION_HANDLE session;
228 CK_OBJECT_HANDLE object;
229 CK_ATTRIBUTE attrs[32];
230 unsigned int n = 0;
231 int rv;
232
233 /* First, make sure we have a session */
234 if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
235 return -1;
236 session = PRIVSLOT(slot)->session;
237
238 /* Now build the template */
239 pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_CERTIFICATE);
240 pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE);
241 pkcs11_addattr_int(attrs + n++, CKA_CERTIFICATE_TYPE, CKC_X_509);
242 pkcs11_addattr_obj(attrs + n++, CKA_VALUE, (pkcs11_i2d_fn) i2d_X509, x509);
243 if (label)
244 pkcs11_addattr_s(attrs + n++, CKA_LABEL, label);
245 if (id && id_len)
246 pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
247
248 /* Now call the pkcs11 module to create the object */
249 rv = CRYPTOKI_call(ctx, C_CreateObject(session, attrs, n, &object));
250
251 /* Zap all memory allocated when building the template */
252 pkcs11_zap_attrs(attrs, n);
253
254 CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_CERTIFICATE, rv);
255
256 /* Gobble the key object */
257 return pkcs11_init_cert(ctx, token, session, object, ret_cert);
258}
diff --git a/src/p11_err.c b/src/p11_err.c
new file mode 100644
index 0000000..ef373fd
--- /dev/null
+++ b/src/p11_err.c
@@ -0,0 +1,160 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#include <config.h>
20#include "libp11-int.h"
21
22/* BEGIN ERROR CODES */
23#ifndef NO_ERR
24static ERR_STRING_DATA PKCS11_str_library[] = {
25 {ERR_PACK(ERR_LIB_PKCS11, 0, 0), "PKCS11 library"},
26 {0, NULL}
27};
28
29static ERR_STRING_DATA PKCS11_str_functs[] = {
30 {ERR_PACK(0, PKCS11_F_PKCS11_CTX_LOAD, 0), "PKCS11_CTX_load"},
31 {ERR_PACK(0, PKCS11_F_PKCS11_ENUM_SLOTS, 0), "PKCS11_enum_slots"},
32 {ERR_PACK(0, PKCS11_F_PKCS11_CHECK_TOKEN, 0), "PKCS11_check_token"},
33 {ERR_PACK(0, PKCS11_F_PKCS11_OPEN_SESSION, 0), "PKCS11_open_session"},
34 {ERR_PACK(0, PKCS11_F_PKCS11_LOGIN, 0), "PKCS11_login"},
35 {ERR_PACK(0, PKCS11_F_PKCS11_ENUM_KEYS, 0), "PKCS11_enum_keys"},
36 {ERR_PACK(0, PKCS11_F_PKCS11_GET_KEY, 0), "PKCS11_get_key"},
37 {ERR_PACK(0, PKCS11_F_PKCS11_RSA_DECRYPT, 0), "PKCS11_rsa_decrypt"},
38 {ERR_PACK(0, PKCS11_F_PKCS11_RSA_ENCRYPT, 0), "PKCS11_rsa_encrypt"},
39 {ERR_PACK(0, PKCS11_F_PKCS11_RSA_SIGN, 0), "PKCS11_rsa_sign"},
40 {ERR_PACK(0, PKCS11_F_PKCS11_RSA_VERIFY, 0), "PKCS11_rsa_verify"},
41 {ERR_PACK(0, PKCS11_F_PKCS11_ENUM_CERTS, 0), "PKCS11_enum_certs"},
42 {ERR_PACK(0, PKCS11_F_PKCS11_INIT_TOKEN, 0), "PKCS11_init_token"},
43 {ERR_PACK(0, PKCS11_F_PKCS11_INIT_PIN, 0), "PKCS11_init_pin"},
44 {ERR_PACK(0, PKCS11_F_PKCS11_GETATTR, 0), "PKCS11_get_attribute"},
45 {ERR_PACK(0, PKCS11_F_PKCS11_LOGOUT, 0), "PKCS11_logout"},
46 {ERR_PACK(0, PKCS11_F_PKCS11_STORE_PRIVATE_KEY, 0), "PKCS11_store_private_key"},
47 {ERR_PACK(0, PKCS11_F_PKCS11_GENERATE_KEY, 0), "PKCS11_generate_key"},
48 {ERR_PACK(0, PKCS11_F_PKCS11_STORE_PUBLIC_KEY, 0), "PKCS11_store_public_key"},
49 {ERR_PACK(0, PKCS11_F_PKCS11_STORE_CERTIFICATE, 0), "PKCS11_store_certificate"},
50 {ERR_PACK(0, PKCS11_F_PKCS11_CHANGE_PIN, 0), "PKCS11_change_pin"},
51 {0, NULL}
52};
53
54static ERR_STRING_DATA PKCS11_str_reasons[] = {
55 {PKCS11_LOAD_MODULE_ERROR, "Unable to load PKCS#11 module"},
56 {PKCS11_MODULE_LOADED_ERROR, "Already loaded module for PKCS11 context"},
57 {PKCS11_SYMBOL_NOT_FOUND_ERROR, "Symbol not found in PKCS#11 module"},
58 {PKCS11_NOT_SUPPORTED, "Not supported"},
59 {PKCS11_NO_SESSION, "No session open"},
60 {CKR_CANCEL, "Cancel"},
61 {CKR_HOST_MEMORY, "Host memory error"},
62 {CKR_SLOT_ID_INVALID, "Invalid slot ID"},
63 {CKR_GENERAL_ERROR, "General Error"},
64 {CKR_FUNCTION_FAILED, "Function failed"},
65 {CKR_ARGUMENTS_BAD, "Invalid arguments"},
66 {CKR_NO_EVENT, "No event"},
67 {CKR_NEED_TO_CREATE_THREADS, "Need to create threads"},
68 {CKR_CANT_LOCK, "Cannott lock"},
69 {CKR_ATTRIBUTE_READ_ONLY, "Attribute read only"},
70 {CKR_ATTRIBUTE_SENSITIVE, "Attribute sensitive"},
71 {CKR_ATTRIBUTE_TYPE_INVALID, "Attribute type invalid"},
72 {CKR_ATTRIBUTE_VALUE_INVALID, "Attribute value invalid"},
73 {CKR_DATA_INVALID, "Data invalid"},
74 {CKR_DATA_LEN_RANGE, "Data len range"},
75 {CKR_DEVICE_ERROR, "Device error"},
76 {CKR_DEVICE_MEMORY, "Device memory"},
77 {CKR_DEVICE_REMOVED, "Device removed"},
78 {CKR_ENCRYPTED_DATA_INVALID, "Encrypted data invalid"},
79 {CKR_ENCRYPTED_DATA_LEN_RANGE, "Encrypted data len range"},
80 {CKR_FUNCTION_CANCELED, "Function canceled"},
81 {CKR_FUNCTION_NOT_PARALLEL, "Function not parallel"},
82 {CKR_FUNCTION_NOT_SUPPORTED, "Function not supported"},
83 {CKR_KEY_HANDLE_INVALID, "Key handle invalid"},
84 {CKR_KEY_SIZE_RANGE, "Key size range"},
85 {CKR_KEY_TYPE_INCONSISTENT, "Key type inconsistent"},
86 {CKR_KEY_NOT_NEEDED, "Key not needed"},
87 {CKR_KEY_CHANGED, "Key changed"},
88 {CKR_KEY_NEEDED, "Key needed"},
89 {CKR_KEY_INDIGESTIBLE, "Key indigestible"},
90 {CKR_KEY_FUNCTION_NOT_PERMITTED, "Key function not permitted"},
91 {CKR_KEY_NOT_WRAPPABLE, "Key not wrappable"},
92 {CKR_KEY_UNEXTRACTABLE, "Key unextractable"},
93 {CKR_MECHANISM_INVALID, "Mechanism invalid"},
94 {CKR_MECHANISM_PARAM_INVALID, "Mechanism param invalid"},
95 {CKR_OBJECT_HANDLE_INVALID, "Object handle invalid"},
96 {CKR_OPERATION_ACTIVE, "Operation active"},
97 {CKR_OPERATION_NOT_INITIALIZED, "Operation not initialized"},
98 {CKR_PIN_INCORRECT, "PIN incorrect"},
99 {CKR_PIN_INVALID, "PIN invalid"},
100 {CKR_PIN_LEN_RANGE, "Invalid PIN length"},
101 {CKR_PIN_EXPIRED, "PIN expired"},
102 {CKR_PIN_LOCKED, "PIN locked"},
103 {CKR_SESSION_CLOSED, "Session closed"},
104 {CKR_SESSION_COUNT, "Session count"},
105 {CKR_SESSION_HANDLE_INVALID, "Session handle invalid"},
106 {CKR_SESSION_PARALLEL_NOT_SUPPORTED, "Session parallel not supported"},
107 {CKR_SESSION_READ_ONLY, "Session read only"},
108 {CKR_SESSION_EXISTS, "Session exists"},
109 {CKR_SESSION_READ_ONLY_EXISTS, "Read-only session exists"},
110 {CKR_SESSION_READ_WRITE_SO_EXISTS, "Read/write SO session exists"},
111 {CKR_SIGNATURE_INVALID, "Signature invalid"},
112 {CKR_SIGNATURE_LEN_RANGE, "Signature len range"},
113 {CKR_TEMPLATE_INCOMPLETE, "Incomplete template"},
114 {CKR_TEMPLATE_INCONSISTENT, "Inconsistent template"},
115 {CKR_TOKEN_NOT_PRESENT, "No PKCS#11 token present"},
116 {CKR_TOKEN_NOT_RECOGNIZED, "PKCS#11 token not recognized"},
117 {CKR_TOKEN_WRITE_PROTECTED, "Token write protected"},
118 {CKR_UNWRAPPING_KEY_HANDLE_INVALID, "Unwrapping key handle invalid"},
119 {CKR_UNWRAPPING_KEY_SIZE_RANGE, "Unwrapping key size range"},
120 {CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "Unwrapping key type inconsistent"},
121 {CKR_USER_ALREADY_LOGGED_IN, "User already logged in"},
122 {CKR_USER_NOT_LOGGED_IN, "User not logged in"},
123 {CKR_USER_PIN_NOT_INITIALIZED, "User pin not initialized"},
124 {CKR_USER_TYPE_INVALID, "User type invalid"},
125 {CKR_USER_ANOTHER_ALREADY_LOGGED_IN, "User another is already logged in"},
126 {CKR_USER_TOO_MANY_TYPES, "User too many types"},
127 {CKR_WRAPPED_KEY_INVALID, "Wrapped key invalid"},
128 {CKR_WRAPPED_KEY_LEN_RANGE, "Wrapped key len range"},
129 {CKR_WRAPPING_KEY_HANDLE_INVALID, "Wrapping key handle invalid"},
130 {CKR_WRAPPING_KEY_SIZE_RANGE, "Wrapping key size range"},
131 {CKR_WRAPPING_KEY_TYPE_INCONSISTENT, "Wrapping key type inconsistent"},
132 {CKR_RANDOM_SEED_NOT_SUPPORTED, "Random seed not supported"},
133 {CKR_RANDOM_NO_RNG, "Random no rng"},
134 {CKR_DOMAIN_PARAMS_INVALID, "Domain params invalid"},
135 {CKR_BUFFER_TOO_SMALL, "Buffer too small"},
136 {CKR_SAVED_STATE_INVALID, "Saved state invalid"},
137 {CKR_INFORMATION_SENSITIVE, "Information sensitive"},
138 {CKR_STATE_UNSAVEABLE, "State unsaveable"},
139 {CKR_CRYPTOKI_NOT_INITIALIZED, "Cryptoki not initialized"},
140 {CKR_CRYPTOKI_ALREADY_INITIALIZED, "Cryptoki already initialized"},
141 {CKR_MUTEX_BAD, "Mutex bad"},
142 {CKR_MUTEX_NOT_LOCKED, "Mutex not locked"},
143 {CKR_VENDOR_DEFINED, "Vendor defined"},
144 {0, NULL}
145};
146#endif
147
148void ERR_load_PKCS11_strings(void)
149{
150 static int init = 1;
151
152 if (init) {
153 init = 0;
154#ifndef NO_ERR
155 ERR_load_strings(0, PKCS11_str_library);
156 ERR_load_strings(ERR_LIB_PKCS11, PKCS11_str_functs);
157 ERR_load_strings(ERR_LIB_PKCS11, PKCS11_str_reasons);
158#endif
159 }
160}
diff --git a/src/p11_key.c b/src/p11_key.c
new file mode 100644
index 0000000..f9672fc
--- /dev/null
+++ b/src/p11_key.c
@@ -0,0 +1,470 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#include <config.h>
20#include <string.h>
21#include "libp11-int.h"
22
23#ifdef _WIN32
24#define strncasecmp strnicmp
25#endif
26
27static int pkcs11_find_keys(PKCS11_TOKEN *, unsigned int);
28static int pkcs11_next_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
29 CK_SESSION_HANDLE session, CK_OBJECT_CLASS type);
30static int pkcs11_init_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
31 CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o,
32 CK_OBJECT_CLASS type, PKCS11_KEY **);
33static int pkcs11_store_private_key(PKCS11_TOKEN *, EVP_PKEY *, char *,
34 unsigned char *, size_t, PKCS11_KEY **);
35static int pkcs11_store_public_key(PKCS11_TOKEN *, EVP_PKEY *, char *,
36 unsigned char *, size_t, PKCS11_KEY **);
37
38static CK_OBJECT_CLASS key_search_class;
39static CK_ATTRIBUTE key_search_attrs[] = {
40 {CKA_CLASS, &key_search_class, sizeof(key_search_class)},
41};
42#define numof(arr) (sizeof(arr)/sizeof((arr)[0]))
43#define MAX_VALUE_LEN 200
44
45/*
46 * Enumerate all keys on the card
47 * For now, we enumerate just the private keys.
48 */
49int
50PKCS11_enumerate_keys(PKCS11_TOKEN * token, PKCS11_KEY ** keyp, unsigned int *countp)
51{
52 PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
53
54 if (priv->nkeys < 0) {
55 priv->nkeys = 0;
56 if (pkcs11_find_keys(token, CKO_PRIVATE_KEY)) {
57 pkcs11_destroy_keys(token);
58 return -1;
59 }
60 priv->nprkeys = priv->nkeys;
61 if (pkcs11_find_keys(token, CKO_PUBLIC_KEY)) {
62 pkcs11_destroy_keys(token);
63 return -1;
64 }
65 }
66 *keyp = priv->keys;
67 *countp = priv->nprkeys;
68 return 0;
69}
70
71/*
72 * Find key matching a certificate
73 */
74PKCS11_KEY *PKCS11_find_key(PKCS11_CERT *cert)
75{
76 PKCS11_CERT_private *cpriv;
77 PKCS11_KEY_private *kpriv;
78 PKCS11_KEY *key;
79 unsigned int n, count;
80
81 cpriv = PRIVCERT(cert);
82 if (PKCS11_enumerate_keys(CERT2TOKEN(cert), &key, &count))
83 return NULL;
84 for (n = 0; n < count; n++, key++) {
85 kpriv = PRIVKEY(key);
86 if (cpriv->id_len == kpriv->id_len
87 && !memcmp(cpriv->id, kpriv->id, cpriv->id_len))
88 return key;
89 }
90 return NULL;
91}
92
93/*
94 * Store a private key on the token
95 */
96int PKCS11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len)
97{
98 if (pkcs11_store_private_key(token, pk, label, id, id_len, NULL))
99 return -1;
100 return 0;
101}
102
103int PKCS11_store_public_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len)
104{
105 if (pkcs11_store_public_key(token, pk, label, id, id_len, NULL))
106 return -1;
107 return 0;
108}
109
110/*
111 * Generate and store a private key on the token
112 * FIXME: We should check first whether the token supports
113 * on-board key generation, and if it does, use its own algorithm
114 */
115int
116PKCS11_generate_key(PKCS11_TOKEN * token,
117 int algorithm, unsigned int bits, char *label, unsigned char* id, size_t id_len)
118{
119 PKCS11_KEY *key_obj;
120 EVP_PKEY *pk;
121 RSA *rsa;
122 BIO *err;
123 int rc;
124
125 if (algorithm != EVP_PKEY_RSA) {
126 PKCS11err(PKCS11_F_PKCS11_GENERATE_KEY, PKCS11_NOT_SUPPORTED);
127 return -1;
128 }
129
130 err = BIO_new_fp(stderr, BIO_NOCLOSE);
131 rsa = RSA_generate_key(bits, 0x10001, NULL, err);
132 BIO_free(err);
133 if (rsa == NULL) {
134 PKCS11err(PKCS11_F_PKCS11_GENERATE_KEY, PKCS11_KEYGEN_FAILED);
135 return -1;
136 }
137
138 pk = EVP_PKEY_new();
139 EVP_PKEY_assign_RSA(pk, rsa);
140 rc = pkcs11_store_private_key(token, pk, label, id, id_len, &key_obj);
141
142 if (rc == 0) {
143 PKCS11_KEY_private *kpriv;
144
145 kpriv = PRIVKEY(key_obj);
146 rc = pkcs11_store_public_key(token, pk, label,
147 kpriv->id, kpriv->id_len, NULL);
148 }
149 EVP_PKEY_free(pk);
150 return rc;
151}
152
153/*
154 * Get the key type
155 */
156int PKCS11_get_key_type(PKCS11_KEY * key)
157{
158 PKCS11_KEY_private *priv = PRIVKEY(key);
159
160 return priv->ops->type;
161}
162
163/*
164 * Create a key object that will allow an OpenSSL application
165 * to use the token via an EVP_PKEY
166 */
167EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY * key)
168{
169 PKCS11_KEY_private *priv = PRIVKEY(key);
170
171 if (key->evp_key == NULL) {
172 EVP_PKEY *pk = EVP_PKEY_new();
173 if (pk == NULL)
174 return NULL;
175 if (priv->ops->get_private(key, pk)
176 || priv->ops->get_public(key, pk)) {
177 EVP_PKEY_free(pk);
178 return NULL;
179 }
180 key->evp_key = pk;
181 }
182
183 return key->evp_key;
184}
185
186EVP_PKEY *PKCS11_get_public_key(PKCS11_KEY * key)
187{
188 return PKCS11_get_private_key(key);
189}
190
191
192/*
193 * Find all keys of a given type (public or private)
194 */
195static int pkcs11_find_keys(PKCS11_TOKEN * token, unsigned int type)
196{
197 PKCS11_SLOT *slot = TOKEN2SLOT(token);
198 PKCS11_CTX *ctx = TOKEN2CTX(token);
199 CK_SESSION_HANDLE session;
200 int rv, res = -1;
201
202 /* Make sure we have a session */
203 if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 0))
204 return -1;
205 session = PRIVSLOT(slot)->session;
206
207 /* Tell the PKCS11 lib to enumerate all matching objects */
208 key_search_class = type;
209 rv = CRYPTOKI_call(ctx, C_FindObjectsInit(session, key_search_attrs,
210 numof(key_search_attrs)));
211 CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_KEYS, rv);
212
213 do {
214 res = pkcs11_next_key(ctx, token, session, type);
215 } while (res == 0);
216
217 CRYPTOKI_call(ctx, C_FindObjectsFinal(session));
218 return (res < 0) ? -1 : 0;
219}
220
221static int pkcs11_next_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
222 CK_SESSION_HANDLE session, CK_OBJECT_CLASS type)
223{
224 CK_OBJECT_HANDLE obj;
225 CK_ULONG count;
226 int rv;
227
228 /* Get the next matching object */
229 rv = CRYPTOKI_call(ctx, C_FindObjects(session, &obj, 1, &count));
230 CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_KEYS, rv);
231
232 if (count == 0)
233 return 1;
234
235 if (pkcs11_init_key(ctx, token, session, obj, type, NULL))
236 return -1;
237
238 return 0;
239}
240
241static int pkcs11_init_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
242 CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj,
243 CK_OBJECT_CLASS type, PKCS11_KEY ** ret)
244{
245 PKCS11_TOKEN_private *tpriv;
246 PKCS11_KEY_private *kpriv;
247 PKCS11_KEY *key, *tmp;
248 char label[256];
249 unsigned char id[256];
250 CK_KEY_TYPE key_type;
251 PKCS11_KEY_ops *ops;
252 size_t size;
253
254 size = sizeof(key_type);
255 if (pkcs11_getattr_var(token, obj, CKA_KEY_TYPE, &key_type, &size))
256 return -1;
257
258 switch (key_type) {
259 case CKK_RSA:
260 ops = &pkcs11_rsa_ops;
261 break;
262 default:
263 /* Ignore any keys we don't understand */
264 return 0;
265 }
266
267 tpriv = PRIVTOKEN(token);
268 tmp = (PKCS11_KEY *) OPENSSL_realloc(tpriv->keys,
269 (tpriv->nkeys + 1) * sizeof(PKCS11_KEY));
270 if (!tmp) {
271 free(tpriv->keys);
272 tpriv->keys = NULL;
273 return -1;
274 }
275 tpriv->keys = tmp;
276
277 key = tpriv->keys + tpriv->nkeys++;
278 memset(key, 0, sizeof(*key));
279 key->_private = kpriv = PKCS11_NEW(PKCS11_KEY_private);
280 kpriv->object = obj;
281 kpriv->parent = token;
282
283 if (!pkcs11_getattr_s(token, obj, CKA_LABEL, label, sizeof(label)))
284 key->label = BUF_strdup(label);
285 key->id_len = sizeof(id);
286 if (!pkcs11_getattr_var(token, obj, CKA_ID, id, &key->id_len)) {
287 key->id = (unsigned char *) malloc(key->id_len);
288 memcpy(key->id, id, key->id_len);
289 }
290 key->isPrivate = (type == CKO_PRIVATE_KEY);
291
292 /* Initialize internal information */
293 kpriv->id_len = sizeof(kpriv->id);
294 if (pkcs11_getattr_var(token, obj, CKA_ID, kpriv->id, &kpriv->id_len))
295 kpriv->id_len = 0;
296 kpriv->ops = ops;
297
298 if (ret)
299 *ret = key;
300 return 0;
301}
302
303/*
304 * Destroy all keys
305 */
306void pkcs11_destroy_keys(PKCS11_TOKEN * token)
307{
308 PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
309
310 while (priv->nkeys > 0) {
311 PKCS11_KEY *key = &priv->keys[--(priv->nkeys)];
312
313 if (key->evp_key)
314 EVP_PKEY_free(key->evp_key);
315 OPENSSL_free(key->label);
316 if (key->id)
317 free(key->id);
318 if (key->_private != NULL)
319 OPENSSL_free(key->_private);
320 }
321 if (priv->keys)
322 OPENSSL_free(priv->keys);
323 priv->nprkeys = -1;
324 priv->nkeys = -1;
325 priv->keys = NULL;
326}
327
328/*
329 * Store private key
330 */
331static int pkcs11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk,
332 char *label, unsigned char *id, size_t id_len,
333 PKCS11_KEY ** ret_key)
334{
335 PKCS11_SLOT *slot = TOKEN2SLOT(token);
336 PKCS11_CTX *ctx = TOKEN2CTX(token);
337 CK_SESSION_HANDLE session;
338 CK_OBJECT_HANDLE object;
339 CK_ATTRIBUTE attrs[32];
340 unsigned int n = 0;
341 int rv;
342
343 /* First, make sure we have a session */
344 if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
345 return -1;
346 session = PRIVSLOT(slot)->session;
347
348 /* Now build the key attrs */
349 if (pk->type == EVP_PKEY_RSA) {
350 RSA *rsa = EVP_PKEY_get1_RSA(pk);
351
352 pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_PRIVATE_KEY);
353 pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA);
354
355 pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE);
356 pkcs11_addattr_bool(attrs + n++, CKA_PRIVATE, TRUE);
357 pkcs11_addattr_bool(attrs + n++, CKA_SENSITIVE, TRUE);
358 pkcs11_addattr_bool(attrs + n++, CKA_DECRYPT, TRUE);
359 pkcs11_addattr_bool(attrs + n++, CKA_SIGN, TRUE);
360 pkcs11_addattr_bool(attrs + n++, CKA_UNWRAP, TRUE);
361
362 pkcs11_addattr_bn(attrs + n++, CKA_MODULUS, rsa->n);
363 pkcs11_addattr_bn(attrs + n++, CKA_PUBLIC_EXPONENT, rsa->e);
364 pkcs11_addattr_bn(attrs + n++, CKA_PRIVATE_EXPONENT, rsa->d);
365 pkcs11_addattr_bn(attrs + n++, CKA_PRIME_1, rsa->p);
366 pkcs11_addattr_bn(attrs + n++, CKA_PRIME_2, rsa->q);
367
368 if (label)
369 pkcs11_addattr_s(attrs + n++, CKA_LABEL, label);
370 if (id && id_len)
371 pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
372
373 } else {
374 PKCS11err(PKCS11_F_PKCS11_STORE_PRIVATE_KEY, PKCS11_NOT_SUPPORTED);
375 return -1;
376 }
377
378 /* Now call the pkcs11 module to create the object */
379 rv = CRYPTOKI_call(ctx, C_CreateObject(session, attrs, n, &object));
380
381 /* Zap all memory allocated when building the template */
382 pkcs11_zap_attrs(attrs, n);
383
384 CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_PRIVATE_KEY, rv);
385
386 /* Gobble the key object */
387 return pkcs11_init_key(ctx, token, session, object,
388 CKO_PRIVATE_KEY, ret_key);
389}
390
391/*
392 * Store public key
393 */
394static int pkcs11_store_public_key(PKCS11_TOKEN * token, EVP_PKEY * pk,
395 char *label, unsigned char *id, size_t id_len,
396 PKCS11_KEY ** ret_key)
397{
398 PKCS11_SLOT *slot = TOKEN2SLOT(token);
399 PKCS11_CTX *ctx = TOKEN2CTX(token);
400 CK_SESSION_HANDLE session;
401 CK_OBJECT_HANDLE object;
402 CK_ATTRIBUTE attrs[32];
403 unsigned int n = 0;
404 int rv;
405
406 /* First, make sure we have a session */
407 if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
408 return -1;
409 session = PRIVSLOT(slot)->session;
410
411 /* Now build the key attrs */
412 if (pk->type == EVP_PKEY_RSA) {
413 RSA *rsa = EVP_PKEY_get1_RSA(pk);
414
415 pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_PUBLIC_KEY);
416 pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA);
417
418 pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE);
419 pkcs11_addattr_bool(attrs + n++, CKA_ENCRYPT, TRUE);
420 pkcs11_addattr_bool(attrs + n++, CKA_VERIFY, TRUE);
421 pkcs11_addattr_bool(attrs + n++, CKA_WRAP, TRUE);
422
423 pkcs11_addattr_bn(attrs + n++, CKA_MODULUS, rsa->n);
424 pkcs11_addattr_bn(attrs + n++, CKA_PUBLIC_EXPONENT, rsa->e);
425 if (label)
426 pkcs11_addattr_s(attrs + n++, CKA_LABEL, label);
427 if (id && id_len)
428 pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
429 } else {
430 PKCS11err(PKCS11_F_PKCS11_STORE_PUBLIC_KEY, PKCS11_NOT_SUPPORTED);
431 return -1;
432 }
433
434 /* Now call the pkcs11 module to create the object */
435 rv = CRYPTOKI_call(ctx, C_CreateObject(session, attrs, n, &object));
436
437 /* Zap all memory allocated when building the template */
438 pkcs11_zap_attrs(attrs, n);
439
440 CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_PUBLIC_KEY, rv);
441
442 /* Gobble the key object */
443 return pkcs11_init_key(ctx, token, session, object, CKO_PUBLIC_KEY, ret_key);
444}
445int PKCS11_get_key_modulus(PKCS11_KEY * key, BIGNUM **bn)
446{
447
448 if (pkcs11_getattr_bn(KEY2TOKEN(key), PRIVKEY(key)->object, CKA_MODULUS, bn))
449 return 0;
450 return 1;
451}
452int PKCS11_get_key_exponent(PKCS11_KEY * key, BIGNUM **bn)
453{
454
455 if (pkcs11_getattr_bn(KEY2TOKEN(key), PRIVKEY(key)->object, CKA_PUBLIC_EXPONENT, bn))
456 return 0;
457 return 1;
458}
459
460
461int PKCS11_get_key_size(const PKCS11_KEY * key)
462{
463 BIGNUM* n = NULL;
464 int numbytes = 0;
465 if(key_getattr_bn(key, CKA_MODULUS, &n))
466 return 0;
467 numbytes = BN_num_bytes(n);
468 BN_free(n);
469 return numbytes;
470}
diff --git a/src/p11_load.c b/src/p11_load.c
new file mode 100644
index 0000000..d315aa6
--- /dev/null
+++ b/src/p11_load.c
@@ -0,0 +1,125 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#include <config.h>
20#include <string.h>
21#include "libp11-int.h"
22
23static void *handle = NULL;
24
25/*
26 * Create a new context
27 */
28PKCS11_CTX *PKCS11_CTX_new(void)
29{
30 PKCS11_CTX_private *priv;
31 PKCS11_CTX *ctx;
32
33 /* Load error strings */
34 ERR_load_PKCS11_strings();
35
36 priv = PKCS11_NEW(PKCS11_CTX_private);
37 ctx = PKCS11_NEW(PKCS11_CTX);
38 ctx->_private = priv;
39
40 return ctx;
41}
42
43/*
44 * Set private init args for module
45 */
46void PKCS11_CTX_init_args(PKCS11_CTX * ctx, const char *init_args)
47{
48 PKCS11_CTX_private *priv = PRIVCTX(ctx);
49 priv->init_args = init_args ? strdup(init_args) : NULL;
50}
51
52/*
53 * Load the shared library, and initialize it.
54 */
55int PKCS11_CTX_load(PKCS11_CTX * ctx, const char *name)
56{
57 PKCS11_CTX_private *priv = PRIVCTX(ctx);
58 CK_C_INITIALIZE_ARGS _args;
59 CK_C_INITIALIZE_ARGS *args = NULL;
60 CK_INFO ck_info;
61 int rv;
62
63 if (priv->libinfo != NULL) {
64 PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_MODULE_LOADED_ERROR);
65 return -1;
66 }
67 handle = C_LoadModule(name, &priv->method);
68 if (!handle) {
69 PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_LOAD_MODULE_ERROR);
70 return -1;
71 }
72
73 /* Tell the PKCS11 to initialize itself */
74 if (priv->init_args != NULL) {
75 memset(&_args, 0, sizeof(_args));
76 args = &_args;
77 args->pReserved = priv->init_args;
78 }
79 rv = priv->method->C_Initialize(args);
80 if (rv && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
81 PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, rv);
82 return -1;
83 }
84
85 /* Get info on the library */
86 rv = priv->method->C_GetInfo(&ck_info);
87 CRYPTOKI_checkerr(PKCS11_F_PKCS11_CTX_LOAD, rv);
88
89 ctx->manufacturer = PKCS11_DUP(ck_info.manufacturerID);
90 ctx->description = PKCS11_DUP(ck_info.libraryDescription);
91
92 return 0;
93}
94
95/*
96 * Unload the shared library
97 */
98void PKCS11_CTX_unload(PKCS11_CTX * ctx)
99{
100 PKCS11_CTX_private *priv;
101 priv = PRIVCTX(ctx);
102
103 /* Tell the PKCS11 library to shut down */
104 priv->method->C_Finalize(NULL);
105
106 /* Unload the module */
107 C_UnloadModule(handle);
108}
109
110/*
111 * Free a context
112 */
113void PKCS11_CTX_free(PKCS11_CTX * ctx)
114{
115 /* Do not remove the strings since OpenSSL strings may still be used by
116 * the application and we can't know
117
118 ERR_free_strings();
119 ERR_remove_state(0);
120 */
121 OPENSSL_free(ctx->manufacturer);
122 OPENSSL_free(ctx->description);
123 OPENSSL_free(ctx->_private);
124 OPENSSL_free(ctx);
125}
diff --git a/src/p11_misc.c b/src/p11_misc.c
new file mode 100644
index 0000000..bfbfce9
--- /dev/null
+++ b/src/p11_misc.c
@@ -0,0 +1,63 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#include <config.h>
20#include <string.h>
21#include <openssl/crypto.h>
22#include "libp11-int.h"
23
24void *pkcs11_malloc(size_t size)
25{
26 void *p = OPENSSL_malloc(size);
27 if (p == NULL)
28 return NULL;
29 memset(p, 0, size);
30 return p;
31}
32
33/* PKCS11 strings are fixed size blank padded,
34 * so when strduping them we must make sure
35 * we stop at the end of the buffer, and while we're
36 * at it it's nice to remove the padding */
37char *pkcs11_strdup(char *mem, size_t size)
38{
39 char *res;
40
41 while (size && mem[size - 1] == ' ')
42 size--;
43 res = (char *) OPENSSL_malloc(size + 1);
44 if (res == NULL)
45 return NULL;
46 memcpy(res, mem, size);
47 res[size] = '\0';
48 return res;
49}
50
51/*
52 * Dup memory
53 */
54void *memdup(const void *src, size_t size)
55{
56 void *dst;
57
58 dst = malloc(size);
59 if (dst == NULL)
60 return NULL;
61 memcpy(dst, src, size);
62 return dst;
63}
diff --git a/src/p11_ops.c b/src/p11_ops.c
new file mode 100644
index 0000000..fb6ad8f
--- /dev/null
+++ b/src/p11_ops.c
@@ -0,0 +1,191 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 * Copyright (C) 2005 Kevin Stefanik <kstef@mtppi.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20
21/* this file does certain cryptographic operations via the pkcs11 library */
22
23#include <config.h>
24#include <string.h>
25#include "libp11-int.h"
26
27int
28PKCS11_sign(int type, const unsigned char *m, unsigned int m_len,
29 unsigned char *sigret, unsigned int *siglen, const PKCS11_KEY * key)
30{
31 int rv, ssl = ((type == NID_md5_sha1) ? 1 : 0);
32 unsigned char *encoded = NULL;
33 int sigsize;
34
35 if (key == NULL)
36 return 0;
37
38 sigsize = PKCS11_get_key_size(key);
39
40 if (ssl) {
41 if((m_len != 36) /* SHA1 + MD5 */ ||
42 ((m_len + RSA_PKCS1_PADDING_SIZE) > sigsize)) {
43 return(0); /* the size is wrong */
44 }
45 } else {
46 ASN1_TYPE parameter = { V_ASN1_NULL, { NULL } };
47 ASN1_STRING digest = { m_len, V_ASN1_OCTET_STRING, (unsigned char *)m };
48 X509_ALGOR algor = { NULL, &parameter };
49 X509_SIG digest_info = { &algor, &digest };
50 int size;
51 /* Fetch the OID of the algorithm used */
52 if((algor.algorithm = OBJ_nid2obj(type)) &&
53 (algor.algorithm->length) &&
54 /* Get the size of the encoded DigestInfo */
55 (size = i2d_X509_SIG(&digest_info, NULL)) &&
56 /* Check that size is compatible with PKCS#11 padding */
57 (size + RSA_PKCS1_PADDING_SIZE <= sigsize) &&
58 (encoded = (unsigned char *) malloc(sigsize))) {
59 unsigned char *tmp = encoded;
60 /* Actually do the encoding */
61 i2d_X509_SIG(&digest_info,&tmp);
62 m = encoded;
63 m_len = size;
64 } else {
65 return(0);
66 }
67 }
68
69 rv = PKCS11_private_encrypt(m_len, m, sigret, key, RSA_PKCS1_PADDING);
70
71 if (rv <= 0)
72 rv = 0;
73 else {
74 *siglen = rv;
75 rv = 1;
76 }
77
78 if (encoded != NULL) /* NULL on SSL case */
79 free(encoded);
80
81 return rv;
82}
83
84int
85PKCS11_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
86 const PKCS11_KEY * key, int padding)
87{
88 PKCS11_KEY_private *priv;
89 PKCS11_SLOT *slot;
90 PKCS11_CTX *ctx;
91 CK_SESSION_HANDLE session;
92 CK_MECHANISM mechanism;
93 int rv;
94 int sigsize;
95 CK_ULONG ck_sigsize;
96
97 if (key == NULL)
98 return -1;
99
100 if (padding != RSA_PKCS1_PADDING) {
101 printf("pkcs11 engine: only RSA_PKCS1_PADDING allowed so far\n");
102 return -1;
103 }
104
105 ctx = KEY2CTX(key);
106 priv = PRIVKEY(key);
107 slot = TOKEN2SLOT(priv->parent);
108 session = PRIVSLOT(slot)->session;
109
110 sigsize=PKCS11_get_key_size(key);
111 ck_sigsize=sigsize;
112
113 if ((flen + RSA_PKCS1_PADDING_SIZE) > sigsize) {
114 return -1; /* the size is wrong */
115 }
116
117 memset(&mechanism, 0, sizeof(mechanism));
118 mechanism.mechanism = CKM_RSA_PKCS;
119
120 /* API is somewhat fishy here. *siglen is 0 on entry (cleared
121 * by OpenSSL). The library assumes that the memory passed
122 * by the caller is always big enough */
123 if((rv = CRYPTOKI_call(ctx, C_SignInit
124 (session, &mechanism, priv->object))) == 0) {
125 rv = CRYPTOKI_call(ctx, C_Sign
126 (session, (CK_BYTE *) from, flen,
127 to, &ck_sigsize));
128 }
129
130 if (rv) {
131 PKCS11err(PKCS11_F_PKCS11_RSA_SIGN, pkcs11_map_err(rv));
132 return -1;
133 }
134
135 if (sigsize != ck_sigsize)
136 return -1;
137
138 return sigsize;
139}
140
141int
142PKCS11_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
143 PKCS11_KEY * key, int padding)
144{
145 CK_RV rv;
146 PKCS11_KEY_private *priv;
147 PKCS11_SLOT *slot;
148 PKCS11_CTX *ctx;
149 CK_SESSION_HANDLE session;
150 CK_MECHANISM mechanism;
151 CK_ULONG size = flen;
152
153 if (padding != RSA_PKCS1_PADDING) {
154 printf("pkcs11 engine: only RSA_PKCS1_PADDING allowed so far\n");
155 return -1;
156 }
157 if (key == NULL)
158 return -1;
159
160 /* PKCS11 calls go here */
161
162 ctx = KEY2CTX(key);
163 priv = PRIVKEY(key);
164 slot = TOKEN2SLOT(priv->parent);
165 session = PRIVSLOT(slot)->session;
166 memset(&mechanism, 0, sizeof(mechanism));
167 mechanism.mechanism = CKM_RSA_PKCS;
168
169 if( (rv = CRYPTOKI_call(ctx, C_DecryptInit(session, &mechanism, priv->object))) == 0) {
170 rv = CRYPTOKI_call(ctx, C_Decrypt
171 (session, (CK_BYTE *) from, (CK_ULONG)flen,
172 (CK_BYTE_PTR)to, &size));
173 }
174
175 if (rv) {
176 PKCS11err(PKCS11_F_PKCS11_RSA_DECRYPT, pkcs11_map_err(rv));
177 }
178
179 return (rv) ? 0 : size;
180}
181
182int
183PKCS11_verify(int type, const unsigned char *m, unsigned int m_len,
184 unsigned char *signature, unsigned int siglen, PKCS11_KEY * key)
185{
186
187 /* PKCS11 calls go here */
188 PKCS11err(PKCS11_F_PKCS11_RSA_VERIFY, PKCS11_NOT_SUPPORTED);
189 return -1;
190}
191
diff --git a/src/p11_rsa.c b/src/p11_rsa.c
new file mode 100644
index 0000000..fa36160
--- /dev/null
+++ b/src/p11_rsa.c
@@ -0,0 +1,158 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19/*
20 * This file implements the handling of RSA keys stored on a
21 * PKCS11 token
22 */
23
24#include <config.h>
25#include <string.h>
26#include <openssl/evp.h>
27#include <openssl/rsa.h>
28#include "libp11-int.h"
29
30static int pkcs11_get_rsa_public(PKCS11_KEY *, EVP_PKEY *);
31static int pkcs11_get_rsa_private(PKCS11_KEY *, EVP_PKEY *);
32
33
34/*
35 * Get RSA key material
36 */
37static int pkcs11_get_rsa_private(PKCS11_KEY * key, EVP_PKEY * pk)
38{
39 CK_BBOOL sensitive, extractable;
40 RSA *rsa;
41
42 if (!(rsa = EVP_PKEY_get1_RSA(pk))) {
43 ERR_clear_error(); /* the above flags an error */
44 rsa = RSA_new();
45 EVP_PKEY_set1_RSA(pk, rsa);
46 }
47
48 if (key_getattr(key, CKA_SENSITIVE, &sensitive, sizeof(sensitive))
49 || key_getattr(key, CKA_EXTRACTABLE, &extractable, sizeof(extractable))) {
50 RSA_free(rsa);
51 return -1;
52 }
53
54 if (key_getattr_bn(key, CKA_MODULUS, &rsa->n) ||
55 key_getattr_bn(key, CKA_PUBLIC_EXPONENT, &rsa->e)) {
56 RSA_free(rsa);
57 return -1;
58 }
59
60 /* If the key is not extractable, create a key object
61 * that will use the card's functions to sign & decrypt */
62 if (sensitive || !extractable) {
63 RSA_set_method(rsa, PKCS11_get_rsa_method());
64 rsa->flags |= RSA_FLAG_SIGN_VER;
65 RSA_set_app_data(rsa, key);
66
67 RSA_free(rsa);
68 return 0;
69 }
70
71 /* TBD - extract RSA private key. */
72 /* In the mean time let's use the card anyway */
73 RSA_set_method(rsa, PKCS11_get_rsa_method());
74 rsa->flags |= RSA_FLAG_SIGN_VER;
75 RSA_set_app_data(rsa, key);
76
77 RSA_free(rsa);
78
79 return 0;
80 /*
81 PKCS11err(PKCS11_F_PKCS11_GET_KEY, PKCS11_NOT_SUPPORTED);
82 return -1;
83 */
84}
85
86static int pkcs11_get_rsa_public(PKCS11_KEY * key, EVP_PKEY * pk)
87{
88 /* TBD */
89 return 0;
90/* return pkcs11_get_rsa_private(key,pk);*/
91}
92
93
94static int pkcs11_rsa_decrypt(int flen, const unsigned char *from,
95 unsigned char *to, RSA * rsa, int padding)
96{
97
98 return PKCS11_private_decrypt( flen, from, to, (PKCS11_KEY *) RSA_get_app_data(rsa), padding);
99}
100
101static int pkcs11_rsa_encrypt(int flen, const unsigned char *from,
102 unsigned char *to, RSA * rsa, int padding)
103{
104 return PKCS11_private_encrypt(flen,from,to,(PKCS11_KEY *) RSA_get_app_data(rsa), padding);
105}
106
107static int pkcs11_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
108 unsigned char *sigret, unsigned int *siglen, const RSA * rsa)
109{
110
111 return PKCS11_sign(type,m,m_len,sigret,siglen,(PKCS11_KEY *) RSA_get_app_data(rsa));
112}
113/* Lousy hack alert. If RSA_verify detects that the key has the
114 * RSA_FLAG_SIGN_VER flags set, it will assume that verification
115 * is implemented externally as well.
116 * We work around this by temporarily cleaning the flag, and
117 * calling RSA_verify once more.
118 */
119static int
120pkcs11_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
121 unsigned char *signature, unsigned int siglen, const RSA * rsa)
122{
123 RSA *r = (RSA *) rsa; /* Ugly hack to get rid of compiler warning */
124 int res;
125
126 if (r->flags & RSA_FLAG_SIGN_VER) {
127 r->flags &= ~RSA_FLAG_SIGN_VER;
128 res = RSA_verify(type, m, m_len, signature, siglen, r);
129 r->flags |= RSA_FLAG_SIGN_VER;
130 } else {
131 PKCS11err(PKCS11_F_PKCS11_RSA_VERIFY, PKCS11_NOT_SUPPORTED);
132 res = 0;
133 }
134 return res;
135}
136
137/*
138 * Overload the default OpenSSL methods for RSA
139 */
140RSA_METHOD *PKCS11_get_rsa_method(void)
141{
142 static RSA_METHOD ops;
143
144 if (!ops.rsa_priv_enc) {
145 ops = *RSA_get_default_method();
146 ops.rsa_priv_enc = pkcs11_rsa_encrypt;
147 ops.rsa_priv_dec = pkcs11_rsa_decrypt;
148 ops.rsa_sign = pkcs11_rsa_sign;
149 ops.rsa_verify = pkcs11_rsa_verify;
150 }
151 return &ops;
152}
153
154PKCS11_KEY_ops pkcs11_rsa_ops = {
155 EVP_PKEY_RSA,
156 pkcs11_get_rsa_public,
157 pkcs11_get_rsa_private
158};
diff --git a/src/p11_slot.c b/src/p11_slot.c
new file mode 100644
index 0000000..40b47f1
--- /dev/null
+++ b/src/p11_slot.c
@@ -0,0 +1,416 @@
1/* libp11, a simple layer on to of PKCS#11 API
2 * Copyright (C) 2005 Olaf Kirch <okir@lst.de>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#include <config.h>
20#include <string.h>
21#include <openssl/buffer.h>
22#include "libp11-int.h"
23
24static int pkcs11_init_slot(PKCS11_CTX *, PKCS11_SLOT *, CK_SLOT_ID);
25static int pkcs11_check_token(PKCS11_CTX *, PKCS11_SLOT *);
26static void pkcs11_destroy_token(PKCS11_TOKEN *);
27
28/*
29 * Get slotid from private
30 */
31unsigned long
32PKCS11_get_slotid_from_slot(PKCS11_SLOT *slot)
33{
34 PKCS11_SLOT_private *priv = PRIVSLOT(slot);
35
36 return priv->id;
37}
38
39/*
40 * Enumerate slots
41 */
42int
43PKCS11_enumerate_slots(PKCS11_CTX * ctx, PKCS11_SLOT ** slotp, unsigned int *countp)
44{
45 PKCS11_CTX_private *priv = PRIVCTX(ctx);
46
47 CK_SLOT_ID *slotid;
48 CK_ULONG nslots, n;
49 PKCS11_SLOT *slots;
50 int rv;
51
52 rv = priv->method->C_GetSlotList(FALSE, NULL_PTR, &nslots);
53 CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv);
54
55 slotid = (CK_SLOT_ID *)OPENSSL_malloc(nslots * sizeof(CK_SLOT_ID));
56 if (slotid == NULL) return (-1);
57
58 rv = priv->method->C_GetSlotList(FALSE, slotid, &nslots);
59 CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv);
60
61 slots = (PKCS11_SLOT *) pkcs11_malloc(nslots * sizeof(PKCS11_SLOT));
62 for (n = 0; n < nslots; n++) {
63 if (pkcs11_init_slot(ctx, &slots[n], slotid[n])) {
64 while (n--)
65 pkcs11_release_slot(ctx, slots + n);
66 OPENSSL_free(slotid);
67 OPENSSL_free(slots);
68 return -1;
69 }
70 }
71
72 *slotp = slots;
73 *countp = nslots;
74 OPENSSL_free(slotid);
75 return 0;
76}
77
78/*
79 * Find a slot with a token that looks "valuable"
80 */
81PKCS11_SLOT *PKCS11_find_token(PKCS11_CTX * ctx, PKCS11_SLOT * slots, unsigned int nslots)
82{
83 PKCS11_SLOT *slot, *best;
84 PKCS11_TOKEN *tok;
85 unsigned int n;
86
87 if (! slots)
88 return NULL;
89
90 best = NULL;
91 for (n = 0, slot = slots; n < nslots; n++, slot++) {
92 if ((tok = slot->token) != NULL) {
93 if (best == NULL
94 || (tok->initialized > best->token->initialized
95 && tok->userPinSet > best->token->userPinSet
96 && tok->loginRequired > best->token->loginRequired))
97 best = slot;
98 }
99 }
100 return best;
101}
102
103/*
104 * Open a session with this slot
105 */
106int PKCS11_open_session(PKCS11_SLOT * slot, int rw)
107{
108 PKCS11_SLOT_private *priv = PRIVSLOT(slot);
109 PKCS11_CTX *ctx = SLOT2CTX(slot);
110 int rv;
111
112 if (priv->haveSession) {
113 CRYPTOKI_call(ctx, C_CloseSession(priv->session));
114 priv->haveSession = 0;
115 }
116 rv = CRYPTOKI_call(ctx,
117 C_OpenSession(priv->id,
118 CKF_SERIAL_SESSION | (rw ? CKF_RW_SESSION :
119 0), NULL, NULL,
120 &priv->session));
121 CRYPTOKI_checkerr(PKCS11_F_PKCS11_OPEN_SESSION, rv);
122 priv->haveSession = 1;
123
124 return 0;
125}
126
127/*
128 * Authenticate with the card
129 */
130int PKCS11_login(PKCS11_SLOT * slot, int so, const char *pin)
131{
132 PKCS11_SLOT_private *priv = PRIVSLOT(slot);
133 PKCS11_CTX *ctx = priv->parent;
134 int rv;
135
136 /* Calling PKCS11_login invalidates all cached
137 * keys we have */
138 if (slot->token)
139 pkcs11_destroy_keys(slot->token);
140 if (priv->loggedIn) {
141 /* already logged in, log out first */
142 if (PKCS11_logout(slot))
143 return -1;
144 }
145 if (!priv->haveSession) {
146 /* SO gets a r/w session by default,
147 * user gets a r/o session by default. */
148 if (PKCS11_open_session(slot, so))
149 return -1;
150 }
151
152 rv = CRYPTOKI_call(ctx, C_Login(priv->session,
153 so ? CKU_SO : CKU_USER,
154 (CK_UTF8CHAR *) pin,
155 pin ? strlen(pin) : 0));
156 if (rv && rv != CKR_USER_ALREADY_LOGGED_IN) /* logged in -> OK */
157 CRYPTOKI_checkerr(PKCS11_F_PKCS11_LOGIN, rv);
158 priv->loggedIn = 1;
159 return 0;
160}
161
162/*
163 * Log out
164 */
165int PKCS11_logout(PKCS11_SLOT * slot)
166{
167 PKCS11_SLOT_private *priv = PRIVSLOT(slot);
168 PKCS11_CTX *ctx = priv->parent;
169 int rv;
170
171 /* Calling PKCS11_logout invalidates all cached
172 * keys we have */
173 if (slot->token)
174 pkcs11_destroy_keys(slot->token);
175 if (!priv->haveSession) {
176 PKCS11err(PKCS11_F_PKCS11_LOGOUT, PKCS11_NO_SESSION);
177 return -1;
178 }
179
180 rv = CRYPTOKI_call(ctx, C_Logout(priv->session));
181 CRYPTOKI_checkerr(PKCS11_F_PKCS11_LOGOUT, rv);
182 priv->loggedIn = 0;
183 return 0;
184}
185
186/*
187 * Initialize the token
188 */
189int PKCS11_init_token(PKCS11_TOKEN * token, const char *pin, const char *label)
190{
191 PKCS11_SLOT_private *priv = PRIVSLOT(TOKEN2SLOT(token));
192 PKCS11_CTX *ctx = priv->parent;
193 int rv;
194
195 if (!label)
196 label = "PKCS#11 Token";
197 rv = CRYPTOKI_call(ctx, C_InitToken(priv->id,
198 (CK_UTF8CHAR *) pin, strlen(pin),
199 (CK_UTF8CHAR *) label));
200 CRYPTOKI_checkerr(PKCS11_F_PKCS11_INIT_TOKEN, rv);
201
202 /* FIXME: how to update the token?
203 * PKCS11_CTX_private *cpriv;
204 * int n;
205 * cpriv = PRIVCTX(ctx);
206 * for (n = 0; n < cpriv->nslots; n++) {
207 * if (pkcs11_check_token(ctx, cpriv->slots + n) < 0)
208 * return -1;
209 * }
210 */
211
212 return 0;
213}
214
215/*
216 * Set the User PIN
217 */
218int PKCS11_init_pin(PKCS11_TOKEN * token, const char *pin)
219{
220 PKCS11_SLOT_private *priv = PRIVSLOT(TOKEN2SLOT(token));
221 PKCS11_CTX *ctx = priv->parent;
222 int len, rv;
223
224 if (!priv->haveSession) {
225 PKCS11err(PKCS11_F_PKCS11_INIT_PIN, PKCS11_NO_SESSION);
226 return -1;
227 }
228
229 len = pin ? strlen(pin) : 0;
230 rv = CRYPTOKI_call(ctx, C_InitPIN(priv->session, (CK_UTF8CHAR *) pin, len));
231 CRYPTOKI_checkerr(PKCS11_F_PKCS11_INIT_PIN, rv);
232
233 return pkcs11_check_token(ctx, TOKEN2SLOT(token));
234}
235
236/*
237 * Change the User PIN
238 */
239int PKCS11_change_pin(PKCS11_SLOT * slot, const char *old_pin,
240 const char *new_pin)
241{
242 PKCS11_SLOT_private *priv = PRIVSLOT(slot);
243 PKCS11_CTX *ctx = priv->parent;
244 int old_len, new_len, rv;
245
246 if (!priv->haveSession) {
247 PKCS11err(PKCS11_F_PKCS11_CHANGE_PIN, PKCS11_NO_SESSION);
248 return -1;
249 }
250
251 old_len = old_pin ? strlen(old_pin) : 0;
252 new_len = new_pin ? strlen(new_pin) : 0;
253 rv = CRYPTOKI_call(ctx, C_SetPIN(priv->session, (CK_UTF8CHAR *) old_pin,
254 old_len, (CK_UTF8CHAR *) new_pin, new_len));
255 CRYPTOKI_checkerr(PKCS11_F_PKCS11_CHANGE_PIN, rv);
256
257 return pkcs11_check_token(ctx, slot);
258}
259
260/*
261 * Seed the random number generator
262 */
263int PKCS11_seed_random(PKCS11_SLOT *slot, const unsigned char *s,
264 unsigned int s_len)
265{
266 PKCS11_SLOT_private *priv = PRIVSLOT(slot);
267 PKCS11_CTX *ctx = priv->parent;
268 int rv;
269
270 if (!priv->haveSession && PKCS11_open_session(slot, 0)) {
271 PKCS11err(PKCS11_F_PKCS11_SEED_RANDOM, PKCS11_NO_SESSION);
272 return -1;
273 }
274
275 rv = CRYPTOKI_call(ctx, C_SeedRandom(priv->session, (CK_BYTE_PTR) s, s_len));
276 CRYPTOKI_checkerr(PKCS11_F_PKCS11_SEED_RANDOM, rv);
277
278 return pkcs11_check_token(ctx, slot);
279}
280
281/*
282 * Generate random numbers
283 */
284int PKCS11_generate_random(PKCS11_SLOT *slot, unsigned char *r,
285 unsigned int r_len)
286{
287 PKCS11_SLOT_private *priv = PRIVSLOT(slot);
288 PKCS11_CTX *ctx = priv->parent;
289 int rv;
290
291 if (!priv->haveSession && PKCS11_open_session(slot, 0)) {
292 PKCS11err(PKCS11_F_PKCS11_GENERATE_RANDOM, PKCS11_NO_SESSION);
293 return -1;
294 }
295
296 rv = CRYPTOKI_call(ctx, C_GenerateRandom(priv->session, (CK_BYTE_PTR) r, r_len));
297 CRYPTOKI_checkerr(PKCS11_F_PKCS11_GENERATE_RANDOM, rv);
298
299 return pkcs11_check_token(ctx, slot);
300}
301
302/*
303 * Helper functions
304 */
305static int pkcs11_init_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot, CK_SLOT_ID id)
306{
307 PKCS11_SLOT_private *priv;
308 CK_SLOT_INFO info;
309 int rv;
310
311 rv = CRYPTOKI_call(ctx, C_GetSlotInfo(id, &info));
312 CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv);
313
314 priv = PKCS11_NEW(PKCS11_SLOT_private);
315 priv->parent = ctx;
316 priv->id = id;
317
318 slot->description = PKCS11_DUP(info.slotDescription);
319 slot->manufacturer = PKCS11_DUP(info.manufacturerID);
320 slot->removable = (info.flags & CKF_REMOVABLE_DEVICE) ? 1 : 0;
321 slot->_private = priv;
322
323 if ((info.flags & CKF_TOKEN_PRESENT) && pkcs11_check_token(ctx, slot))
324 return -1;
325
326 return 0;
327}
328
329void PKCS11_release_all_slots(PKCS11_CTX * ctx, PKCS11_SLOT *slots, unsigned int nslots)
330{
331 int i;
332
333 for (i=0; i < nslots; i++)
334 pkcs11_release_slot(ctx, &slots[i]);
335 OPENSSL_free(slots);
336}
337
338void pkcs11_release_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot)
339{
340 PKCS11_SLOT_private *priv = PRIVSLOT(slot);
341
342 if (priv)
343 CRYPTOKI_call(ctx, C_CloseAllSessions(priv->id));
344 OPENSSL_free(slot->_private);
345 OPENSSL_free(slot->description);
346 OPENSSL_free(slot->manufacturer);
347 if (slot->token) {
348 pkcs11_destroy_token(slot->token);
349 OPENSSL_free(slot->token);
350 }
351 memset(slot, 0, sizeof(*slot));
352}
353
354static int pkcs11_check_token(PKCS11_CTX * ctx, PKCS11_SLOT * slot)
355{
356 PKCS11_SLOT_private *priv = PRIVSLOT(slot);
357 PKCS11_TOKEN_private *tpriv;
358 CK_TOKEN_INFO info;
359 PKCS11_TOKEN *token;
360 int rv;
361
362 if (slot->token)
363 pkcs11_destroy_token(slot->token);
364 else
365 slot->token = PKCS11_NEW(PKCS11_TOKEN);
366 token = slot->token;
367
368 rv = CRYPTOKI_call(ctx, C_GetTokenInfo(priv->id, &info));
369 if (rv == CKR_TOKEN_NOT_PRESENT || rv == CKR_TOKEN_NOT_RECOGNIZED) {
370 OPENSSL_free(token);
371 slot->token = NULL;
372 return 0;
373 }
374 CRYPTOKI_checkerr(PKCS11_F_PKCS11_CHECK_TOKEN, rv);
375
376 /* We have a token */
377 tpriv = PKCS11_NEW(PKCS11_TOKEN_private);
378 tpriv->parent = slot;
379 tpriv->nkeys = -1;
380 tpriv->ncerts = -1;
381
382 token->label = PKCS11_DUP(info.label);
383 token->manufacturer = PKCS11_DUP(info.manufacturerID);
384 token->model = PKCS11_DUP(info.model);
385 token->serialnr = PKCS11_DUP(info.serialNumber);
386 token->initialized = (info.flags & CKF_TOKEN_INITIALIZED) ? 1 : 0;
387 token->loginRequired = (info.flags & CKF_LOGIN_REQUIRED) ? 1 : 0;
388 token->secureLogin = (info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ? 1 : 0;
389 token->userPinSet = (info.flags & CKF_USER_PIN_INITIALIZED) ? 1 : 0;
390 token->readOnly = (info.flags & CKF_WRITE_PROTECTED) ? 1 : 0;
391 token->hasRng = (info.flags & CKF_RNG) ? 1 : 0;
392 token->userPinCountLow = (info.flags & CKF_USER_PIN_COUNT_LOW) ? 1 : 0;
393 token->userPinFinalTry = (info.flags & CKF_USER_PIN_FINAL_TRY) ? 1 : 0;
394 token->userPinLocked = (info.flags & CKF_USER_PIN_LOCKED) ? 1 : 0;
395 token->userPinToBeChanged = (info.flags & CKF_USER_PIN_TO_BE_CHANGED) ? 1 : 0;
396 token->soPinCountLow = (info.flags & CKF_SO_PIN_COUNT_LOW) ? 1 : 0;
397 token->soPinFinalTry = (info.flags & CKF_SO_PIN_FINAL_TRY) ? 1 : 0;
398 token->soPinLocked = (info.flags & CKF_SO_PIN_LOCKED) ? 1 : 0;
399 token->soPinToBeChanged = (info.flags & CKF_SO_PIN_TO_BE_CHANGED) ? 1 : 0;
400 token->_private = tpriv;
401
402 return 0;
403}
404
405static void pkcs11_destroy_token(PKCS11_TOKEN * token)
406{
407 pkcs11_destroy_keys(token);
408 pkcs11_destroy_certs(token);
409
410 OPENSSL_free(token->label);
411 OPENSSL_free(token->manufacturer);
412 OPENSSL_free(token->model);
413 OPENSSL_free(token->serialnr);
414 OPENSSL_free(token->_private);
415 memset(token, 0, sizeof(*token));
416}
diff --git a/src/pkcs11.h b/src/pkcs11.h
new file mode 100644
index 0000000..52cd17d
--- /dev/null
+++ b/src/pkcs11.h
@@ -0,0 +1,1357 @@
1/* pkcs11.h
2 Copyright 2006, 2007 g10 Code GmbH
3 Copyright 2006 Andreas Jellinghaus
4
5 This file is free software; as a special exception the author gives
6 unlimited permission to copy and/or distribute it, with or without
7 modifications, as long as this notice is preserved.
8
9 This file is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY, to the extent permitted by law; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. */
13
14/* Please submit changes back to the Scute project at
15 http://www.scute.org/ (or send them to marcus@g10code.com), so that
16 they can be picked up by other projects from there as well. */
17
18/* This file is a modified implementation of the PKCS #11 standard by
19 RSA Security Inc. It is mostly a drop-in replacement, with the
20 following change:
21
22 This header file does not require any macro definitions by the user
23 (like CK_DEFINE_FUNCTION etc). In fact, it defines those macros
24 for you (if useful, some are missing, let me know if you need
25 more).
26
27 There is an additional API available that does comply better to the
28 GNU coding standard. It can be switched on by defining
29 CRYPTOKI_GNU before including this header file. For this, the
30 following changes are made to the specification:
31
32 All structure types are changed to a "struct ck_foo" where CK_FOO
33 is the type name in PKCS #11.
34
35 All non-structure types are changed to ck_foo_t where CK_FOO is the
36 lowercase version of the type name in PKCS #11. The basic types
37 (CK_ULONG et al.) are removed without substitute.
38
39 All members of structures are modified in the following way: Type
40 indication prefixes are removed, and underscore characters are
41 inserted before words. Then the result is lowercased.
42
43 Note that function names are still in the original case, as they
44 need for ABI compatibility.
45
46 CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute. Use
47 <stdbool.h>.
48
49 If CRYPTOKI_COMPAT is defined before including this header file,
50 then none of the API changes above take place, and the API is the
51 one defined by the PKCS #11 standard. */
52
53#ifndef PKCS11_H
54#define PKCS11_H 1
55
56#if defined(__cplusplus)
57extern "C" {
58#endif
59
60
61/* The version of cryptoki we implement. The revision is changed with
62 each modification of this file. If you do not use the "official"
63 version of this file, please consider deleting the revision macro
64 (you may use a macro with a different name to keep track of your
65 versions). */
66#define CRYPTOKI_VERSION_MAJOR 2
67#define CRYPTOKI_VERSION_MINOR 20
68#define CRYPTOKI_VERSION_REVISION 6
69
70
71/* Compatibility interface is default, unless CRYPTOKI_GNU is
72 given. */
73#ifndef CRYPTOKI_GNU
74#ifndef CRYPTOKI_COMPAT
75#define CRYPTOKI_COMPAT 1
76#endif
77#endif
78
79/* System dependencies. */
80
81#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32)
82
83/* There is a matching pop below. */
84#pragma pack(push, cryptoki, 1)
85
86#ifdef CRYPTOKI_EXPORTS
87#define CK_SPEC __declspec(dllexport)
88#else
89#define CK_SPEC __declspec(dllimport)
90#endif
91
92#else
93
94#define CK_SPEC
95
96#endif
97
98
99#ifdef CRYPTOKI_COMPAT
100 /* If we are in compatibility mode, switch all exposed names to the
101 PKCS #11 variant. There are corresponding #undefs below. */
102
103#define ck_flags_t CK_FLAGS
104#define ck_version _CK_VERSION
105
106#define ck_info _CK_INFO
107#define cryptoki_version cryptokiVersion
108#define manufacturer_id manufacturerID
109#define library_description libraryDescription
110#define library_version libraryVersion
111
112#define ck_notification_t CK_NOTIFICATION
113#define ck_slot_id_t CK_SLOT_ID
114
115#define ck_slot_info _CK_SLOT_INFO
116#define slot_description slotDescription
117#define hardware_version hardwareVersion
118#define firmware_version firmwareVersion
119
120#define ck_token_info _CK_TOKEN_INFO
121#define serial_number serialNumber
122#define max_session_count ulMaxSessionCount
123#define session_count ulSessionCount
124#define max_rw_session_count ulMaxRwSessionCount
125#define rw_session_count ulRwSessionCount
126#define max_pin_len ulMaxPinLen
127#define min_pin_len ulMinPinLen
128#define total_public_memory ulTotalPublicMemory
129#define free_public_memory ulFreePublicMemory
130#define total_private_memory ulTotalPrivateMemory
131#define free_private_memory ulFreePrivateMemory
132#define utc_time utcTime
133
134#define ck_session_handle_t CK_SESSION_HANDLE
135#define ck_user_type_t CK_USER_TYPE
136#define ck_state_t CK_STATE
137
138#define ck_session_info _CK_SESSION_INFO
139#define slot_id slotID
140#define device_error ulDeviceError
141
142#define ck_object_handle_t CK_OBJECT_HANDLE
143#define ck_object_class_t CK_OBJECT_CLASS
144#define ck_hw_feature_type_t CK_HW_FEATURE_TYPE
145#define ck_key_type_t CK_KEY_TYPE
146#define ck_certificate_type_t CK_CERTIFICATE_TYPE
147#define ck_attribute_type_t CK_ATTRIBUTE_TYPE
148
149#define ck_attribute _CK_ATTRIBUTE
150#define value pValue
151#define value_len ulValueLen
152
153#define ck_date _CK_DATE
154
155#define ck_mechanism_type_t CK_MECHANISM_TYPE
156
157#define ck_mechanism _CK_MECHANISM
158#define parameter pParameter
159#define parameter_len ulParameterLen
160
161#define ck_mechanism_info _CK_MECHANISM_INFO
162#define min_key_size ulMinKeySize
163#define max_key_size ulMaxKeySize
164
165#define ck_rv_t CK_RV
166#define ck_notify_t CK_NOTIFY
167
168#define ck_function_list _CK_FUNCTION_LIST
169
170#define ck_createmutex_t CK_CREATEMUTEX
171#define ck_destroymutex_t CK_DESTROYMUTEX
172#define ck_lockmutex_t CK_LOCKMUTEX
173#define ck_unlockmutex_t CK_UNLOCKMUTEX
174
175#define ck_c_initialize_args _CK_C_INITIALIZE_ARGS
176#define create_mutex CreateMutex
177#define destroy_mutex DestroyMutex
178#define lock_mutex LockMutex
179#define unlock_mutex UnlockMutex
180#define reserved pReserved
181
182#endif /* CRYPTOKI_COMPAT */
183
184
185
186typedef unsigned long ck_flags_t;
187
188struct ck_version
189{
190 unsigned char major;
191 unsigned char minor;
192};
193
194
195struct ck_info
196{
197 struct ck_version cryptoki_version;
198 unsigned char manufacturer_id[32];
199 ck_flags_t flags;
200 unsigned char library_description[32];
201 struct ck_version library_version;
202};
203
204
205typedef unsigned long ck_notification_t;
206
207#define CKN_SURRENDER (0)
208
209
210typedef unsigned long ck_slot_id_t;
211
212
213struct ck_slot_info
214{
215 unsigned char slot_description[64];
216 unsigned char manufacturer_id[32];
217 ck_flags_t flags;
218 struct ck_version hardware_version;
219 struct ck_version firmware_version;
220};
221
222
223#define CKF_TOKEN_PRESENT (1 << 0)
224#define CKF_REMOVABLE_DEVICE (1 << 1)
225#define CKF_HW_SLOT (1 << 2)
226#define CKF_ARRAY_ATTRIBUTE (1 << 30)
227
228
229struct ck_token_info
230{
231 unsigned char label[32];
232 unsigned char manufacturer_id[32];
233 unsigned char model[16];
234 unsigned char serial_number[16];
235 ck_flags_t flags;
236 unsigned long max_session_count;
237 unsigned long session_count;
238 unsigned long max_rw_session_count;
239 unsigned long rw_session_count;
240 unsigned long max_pin_len;
241 unsigned long min_pin_len;
242 unsigned long total_public_memory;
243 unsigned long free_public_memory;
244 unsigned long total_private_memory;
245 unsigned long free_private_memory;
246 struct ck_version hardware_version;
247 struct ck_version firmware_version;
248 unsigned char utc_time[16];
249};
250
251
252#define CKF_RNG (1 << 0)
253#define CKF_WRITE_PROTECTED (1 << 1)
254#define CKF_LOGIN_REQUIRED (1 << 2)
255#define CKF_USER_PIN_INITIALIZED (1 << 3)
256#define CKF_RESTORE_KEY_NOT_NEEDED (1 << 5)
257#define CKF_CLOCK_ON_TOKEN (1 << 6)
258#define CKF_PROTECTED_AUTHENTICATION_PATH (1 << 8)
259#define CKF_DUAL_CRYPTO_OPERATIONS (1 << 9)
260#define CKF_TOKEN_INITIALIZED (1 << 10)
261#define CKF_SECONDARY_AUTHENTICATION (1 << 11)
262#define CKF_USER_PIN_COUNT_LOW (1 << 16)
263#define CKF_USER_PIN_FINAL_TRY (1 << 17)
264#define CKF_USER_PIN_LOCKED (1 << 18)
265#define CKF_USER_PIN_TO_BE_CHANGED (1 << 19)
266#define CKF_SO_PIN_COUNT_LOW (1 << 20)
267#define CKF_SO_PIN_FINAL_TRY (1 << 21)
268#define CKF_SO_PIN_LOCKED (1 << 22)
269#define CKF_SO_PIN_TO_BE_CHANGED (1 << 23)
270
271#define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1)
272#define CK_EFFECTIVELY_INFINITE (0)
273
274
275typedef unsigned long ck_session_handle_t;
276
277#define CK_INVALID_HANDLE (0)
278
279
280typedef unsigned long ck_user_type_t;
281
282#define CKU_SO (0)
283#define CKU_USER (1)
284#define CKU_CONTEXT_SPECIFIC (2)
285
286
287typedef unsigned long ck_state_t;
288
289#define CKS_RO_PUBLIC_SESSION (0)
290#define CKS_RO_USER_FUNCTIONS (1)
291#define CKS_RW_PUBLIC_SESSION (2)
292#define CKS_RW_USER_FUNCTIONS (3)
293#define CKS_RW_SO_FUNCTIONS (4)
294
295
296struct ck_session_info
297{
298 ck_slot_id_t slot_id;
299 ck_state_t state;
300 ck_flags_t flags;
301 unsigned long device_error;
302};
303
304#define CKF_RW_SESSION (1 << 1)
305#define CKF_SERIAL_SESSION (1 << 2)
306
307
308typedef unsigned long ck_object_handle_t;
309
310
311typedef unsigned long ck_object_class_t;
312
313#define CKO_DATA (0)
314#define CKO_CERTIFICATE (1)
315#define CKO_PUBLIC_KEY (2)
316#define CKO_PRIVATE_KEY (3)
317#define CKO_SECRET_KEY (4)
318#define CKO_HW_FEATURE (5)
319#define CKO_DOMAIN_PARAMETERS (6)
320#define CKO_MECHANISM (7)
321#define CKO_VENDOR_DEFINED ((unsigned long) (1 << 31))
322
323
324typedef unsigned long ck_hw_feature_type_t;
325
326#define CKH_MONOTONIC_COUNTER (1)
327#define CKH_CLOCK (2)
328#define CKH_USER_INTERFACE (3)
329#define CKH_VENDOR_DEFINED ((unsigned long) (1 << 31))
330
331
332typedef unsigned long ck_key_type_t;
333
334#define CKK_RSA (0)
335#define CKK_DSA (1)
336#define CKK_DH (2)
337#define CKK_ECDSA (3)
338#define CKK_EC (3)
339#define CKK_X9_42_DH (4)
340#define CKK_KEA (5)
341#define CKK_GENERIC_SECRET (0x10)
342#define CKK_RC2 (0x11)
343#define CKK_RC4 (0x12)
344#define CKK_DES (0x13)
345#define CKK_DES2 (0x14)
346#define CKK_DES3 (0x15)
347#define CKK_CAST (0x16)
348#define CKK_CAST3 (0x17)
349#define CKK_CAST128 (0x18)
350#define CKK_RC5 (0x19)
351#define CKK_IDEA (0x1a)
352#define CKK_SKIPJACK (0x1b)
353#define CKK_BATON (0x1c)
354#define CKK_JUNIPER (0x1d)
355#define CKK_CDMF (0x1e)
356#define CKK_AES (0x1f)
357#define CKK_BLOWFISH (0x20)
358#define CKK_TWOFISH (0x21)
359#define CKK_VENDOR_DEFINED ((unsigned long) (1 << 31))
360
361
362typedef unsigned long ck_certificate_type_t;
363
364#define CKC_X_509 (0)
365#define CKC_X_509_ATTR_CERT (1)
366#define CKC_WTLS (2)
367#define CKC_VENDOR_DEFINED ((unsigned long) (1 << 31))
368
369
370typedef unsigned long ck_attribute_type_t;
371
372#define CKA_CLASS (0)
373#define CKA_TOKEN (1)
374#define CKA_PRIVATE (2)
375#define CKA_LABEL (3)
376#define CKA_APPLICATION (0x10)
377#define CKA_VALUE (0x11)
378#define CKA_OBJECT_ID (0x12)
379#define CKA_CERTIFICATE_TYPE (0x80)
380#define CKA_ISSUER (0x81)
381#define CKA_SERIAL_NUMBER (0x82)
382#define CKA_AC_ISSUER (0x83)
383#define CKA_OWNER (0x84)
384#define CKA_ATTR_TYPES (0x85)
385#define CKA_TRUSTED (0x86)
386#define CKA_CERTIFICATE_CATEGORY (0x87)
387#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88)
388#define CKA_URL (0x89)
389#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8a)
390#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8b)
391#define CKA_CHECK_VALUE (0x90)
392#define CKA_KEY_TYPE (0x100)
393#define CKA_SUBJECT (0x101)
394#define CKA_ID (0x102)
395#define CKA_SENSITIVE (0x103)
396#define CKA_ENCRYPT (0x104)
397#define CKA_DECRYPT (0x105)
398#define CKA_WRAP (0x106)
399#define CKA_UNWRAP (0x107)
400#define CKA_SIGN (0x108)
401#define CKA_SIGN_RECOVER (0x109)
402#define CKA_VERIFY (0x10a)
403#define CKA_VERIFY_RECOVER (0x10b)
404#define CKA_DERIVE (0x10c)
405#define CKA_START_DATE (0x110)
406#define CKA_END_DATE (0x111)
407#define CKA_MODULUS (0x120)
408#define CKA_MODULUS_BITS (0x121)
409#define CKA_PUBLIC_EXPONENT (0x122)
410#define CKA_PRIVATE_EXPONENT (0x123)
411#define CKA_PRIME_1 (0x124)
412#define CKA_PRIME_2 (0x125)
413#define CKA_EXPONENT_1 (0x126)
414#define CKA_EXPONENT_2 (0x127)
415#define CKA_COEFFICIENT (0x128)
416#define CKA_PRIME (0x130)
417#define CKA_SUBPRIME (0x131)
418#define CKA_BASE (0x132)
419#define CKA_PRIME_BITS (0x133)
420#define CKA_SUB_PRIME_BITS (0x134)
421#define CKA_VALUE_BITS (0x160)
422#define CKA_VALUE_LEN (0x161)
423#define CKA_EXTRACTABLE (0x162)
424#define CKA_LOCAL (0x163)
425#define CKA_NEVER_EXTRACTABLE (0x164)
426#define CKA_ALWAYS_SENSITIVE (0x165)
427#define CKA_KEY_GEN_MECHANISM (0x166)
428#define CKA_MODIFIABLE (0x170)
429#define CKA_ECDSA_PARAMS (0x180)
430#define CKA_EC_PARAMS (0x180)
431#define CKA_EC_POINT (0x181)
432#define CKA_SECONDARY_AUTH (0x200)
433#define CKA_AUTH_PIN_FLAGS (0x201)
434#define CKA_ALWAYS_AUTHENTICATE (0x202)
435#define CKA_WRAP_WITH_TRUSTED (0x210)
436#define CKA_HW_FEATURE_TYPE (0x300)
437#define CKA_RESET_ON_INIT (0x301)
438#define CKA_HAS_RESET (0x302)
439#define CKA_PIXEL_X (0x400)
440#define CKA_PIXEL_Y (0x401)
441#define CKA_RESOLUTION (0x402)
442#define CKA_CHAR_ROWS (0x403)
443#define CKA_CHAR_COLUMNS (0x404)
444#define CKA_COLOR (0x405)
445#define CKA_BITS_PER_PIXEL (0x406)
446#define CKA_CHAR_SETS (0x480)
447#define CKA_ENCODING_METHODS (0x481)
448#define CKA_MIME_TYPES (0x482)
449#define CKA_MECHANISM_TYPE (0x500)
450#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501)
451#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502)
452#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503)
453#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211)
454#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212)
455#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600)
456#define CKA_VENDOR_DEFINED ((unsigned long) (1 << 31))
457
458
459struct ck_attribute
460{
461 ck_attribute_type_t type;
462 void *value;
463 size_t value_len;
464};
465
466
467struct ck_date
468{
469 unsigned char year[4];
470 unsigned char month[2];
471 unsigned char day[2];
472};
473
474
475typedef unsigned long ck_mechanism_type_t;
476
477#define CKM_RSA_PKCS_KEY_PAIR_GEN (0)
478#define CKM_RSA_PKCS (1)
479#define CKM_RSA_9796 (2)
480#define CKM_RSA_X_509 (3)
481#define CKM_MD2_RSA_PKCS (4)
482#define CKM_MD5_RSA_PKCS (5)
483#define CKM_SHA1_RSA_PKCS (6)
484#define CKM_RIPEMD128_RSA_PKCS (7)
485#define CKM_RIPEMD160_RSA_PKCS (8)
486#define CKM_RSA_PKCS_OAEP (9)
487#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xa)
488#define CKM_RSA_X9_31 (0xb)
489#define CKM_SHA1_RSA_X9_31 (0xc)
490#define CKM_RSA_PKCS_PSS (0xd)
491#define CKM_SHA1_RSA_PKCS_PSS (0xe)
492#define CKM_DSA_KEY_PAIR_GEN (0x10)
493#define CKM_DSA (0x11)
494#define CKM_DSA_SHA1 (0x12)
495#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20)
496#define CKM_DH_PKCS_DERIVE (0x21)
497#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30)
498#define CKM_X9_42_DH_DERIVE (0x31)
499#define CKM_X9_42_DH_HYBRID_DERIVE (0x32)
500#define CKM_X9_42_MQV_DERIVE (0x33)
501#define CKM_SHA256_RSA_PKCS (0x40)
502#define CKM_SHA384_RSA_PKCS (0x41)
503#define CKM_SHA512_RSA_PKCS (0x42)
504#define CKM_SHA256_RSA_PKCS_PSS (0x43)
505#define CKM_SHA384_RSA_PKCS_PSS (0x44)
506#define CKM_SHA512_RSA_PKCS_PSS (0x45)
507#define CKM_RC2_KEY_GEN (0x100)
508#define CKM_RC2_ECB (0x101)
509#define CKM_RC2_CBC (0x102)
510#define CKM_RC2_MAC (0x103)
511#define CKM_RC2_MAC_GENERAL (0x104)
512#define CKM_RC2_CBC_PAD (0x105)
513#define CKM_RC4_KEY_GEN (0x110)
514#define CKM_RC4 (0x111)
515#define CKM_DES_KEY_GEN (0x120)
516#define CKM_DES_ECB (0x121)
517#define CKM_DES_CBC (0x122)
518#define CKM_DES_MAC (0x123)
519#define CKM_DES_MAC_GENERAL (0x124)
520#define CKM_DES_CBC_PAD (0x125)
521#define CKM_DES2_KEY_GEN (0x130)
522#define CKM_DES3_KEY_GEN (0x131)
523#define CKM_DES3_ECB (0x132)
524#define CKM_DES3_CBC (0x133)
525#define CKM_DES3_MAC (0x134)
526#define CKM_DES3_MAC_GENERAL (0x135)
527#define CKM_DES3_CBC_PAD (0x136)
528#define CKM_CDMF_KEY_GEN (0x140)
529#define CKM_CDMF_ECB (0x141)
530#define CKM_CDMF_CBC (0x142)
531#define CKM_CDMF_MAC (0x143)
532#define CKM_CDMF_MAC_GENERAL (0x144)
533#define CKM_CDMF_CBC_PAD (0x145)
534#define CKM_MD2 (0x200)
535#define CKM_MD2_HMAC (0x201)
536#define CKM_MD2_HMAC_GENERAL (0x202)
537#define CKM_MD5 (0x210)
538#define CKM_MD5_HMAC (0x211)
539#define CKM_MD5_HMAC_GENERAL (0x212)
540#define CKM_SHA_1 (0x220)
541#define CKM_SHA_1_HMAC (0x221)
542#define CKM_SHA_1_HMAC_GENERAL (0x222)
543#define CKM_RIPEMD128 (0x230)
544#define CKM_RIPEMD128_HMAC (0x231)
545#define CKM_RIPEMD128_HMAC_GENERAL (0x232)
546#define CKM_RIPEMD160 (0x240)
547#define CKM_RIPEMD160_HMAC (0x241)
548#define CKM_RIPEMD160_HMAC_GENERAL (0x242)
549#define CKM_SHA256 (0x250)
550#define CKM_SHA256_HMAC (0x251)
551#define CKM_SHA256_HMAC_GENERAL (0x252)
552#define CKM_SHA384 (0x260)
553#define CKM_SHA384_HMAC (0x261)
554#define CKM_SHA384_HMAC_GENERAL (0x262)
555#define CKM_SHA512 (0x270)
556#define CKM_SHA512_HMAC (0x271)
557#define CKM_SHA512_HMAC_GENERAL (0x272)
558#define CKM_CAST_KEY_GEN (0x300)
559#define CKM_CAST_ECB (0x301)
560#define CKM_CAST_CBC (0x302)
561#define CKM_CAST_MAC (0x303)
562#define CKM_CAST_MAC_GENERAL (0x304)
563#define CKM_CAST_CBC_PAD (0x305)
564#define CKM_CAST3_KEY_GEN (0x310)
565#define CKM_CAST3_ECB (0x311)
566#define CKM_CAST3_CBC (0x312)
567#define CKM_CAST3_MAC (0x313)
568#define CKM_CAST3_MAC_GENERAL (0x314)
569#define CKM_CAST3_CBC_PAD (0x315)
570#define CKM_CAST5_KEY_GEN (0x320)
571#define CKM_CAST128_KEY_GEN (0x320)
572#define CKM_CAST5_ECB (0x321)
573#define CKM_CAST128_ECB (0x321)
574#define CKM_CAST5_CBC (0x322)
575#define CKM_CAST128_CBC (0x322)
576#define CKM_CAST5_MAC (0x323)
577#define CKM_CAST128_MAC (0x323)
578#define CKM_CAST5_MAC_GENERAL (0x324)
579#define CKM_CAST128_MAC_GENERAL (0x324)
580#define CKM_CAST5_CBC_PAD (0x325)
581#define CKM_CAST128_CBC_PAD (0x325)
582#define CKM_RC5_KEY_GEN (0x330)
583#define CKM_RC5_ECB (0x331)
584#define CKM_RC5_CBC (0x332)
585#define CKM_RC5_MAC (0x333)
586#define CKM_RC5_MAC_GENERAL (0x334)
587#define CKM_RC5_CBC_PAD (0x335)
588#define CKM_IDEA_KEY_GEN (0x340)
589#define CKM_IDEA_ECB (0x341)
590#define CKM_IDEA_CBC (0x342)
591#define CKM_IDEA_MAC (0x343)
592#define CKM_IDEA_MAC_GENERAL (0x344)
593#define CKM_IDEA_CBC_PAD (0x345)
594#define CKM_GENERIC_SECRET_KEY_GEN (0x350)
595#define CKM_CONCATENATE_BASE_AND_KEY (0x360)
596#define CKM_CONCATENATE_BASE_AND_DATA (0x362)
597#define CKM_CONCATENATE_DATA_AND_BASE (0x363)
598#define CKM_XOR_BASE_AND_DATA (0x364)
599#define CKM_EXTRACT_KEY_FROM_KEY (0x365)
600#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370)
601#define CKM_SSL3_MASTER_KEY_DERIVE (0x371)
602#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372)
603#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373)
604#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374)
605#define CKM_TLS_MASTER_KEY_DERIVE (0x375)
606#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376)
607#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377)
608#define CKM_SSL3_MD5_MAC (0x380)
609#define CKM_SSL3_SHA1_MAC (0x381)
610#define CKM_MD5_KEY_DERIVATION (0x390)
611#define CKM_MD2_KEY_DERIVATION (0x391)
612#define CKM_SHA1_KEY_DERIVATION (0x392)
613#define CKM_PBE_MD2_DES_CBC (0x3a0)
614#define CKM_PBE_MD5_DES_CBC (0x3a1)
615#define CKM_PBE_MD5_CAST_CBC (0x3a2)
616#define CKM_PBE_MD5_CAST3_CBC (0x3a3)
617#define CKM_PBE_MD5_CAST5_CBC (0x3a4)
618#define CKM_PBE_MD5_CAST128_CBC (0x3a4)
619#define CKM_PBE_SHA1_CAST5_CBC (0x3a5)
620#define CKM_PBE_SHA1_CAST128_CBC (0x3a5)
621#define CKM_PBE_SHA1_RC4_128 (0x3a6)
622#define CKM_PBE_SHA1_RC4_40 (0x3a7)
623#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8)
624#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9)
625#define CKM_PBE_SHA1_RC2_128_CBC (0x3aa)
626#define CKM_PBE_SHA1_RC2_40_CBC (0x3ab)
627#define CKM_PKCS5_PBKD2 (0x3b0)
628#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0)
629#define CKM_KEY_WRAP_LYNKS (0x400)
630#define CKM_KEY_WRAP_SET_OAEP (0x401)
631#define CKM_SKIPJACK_KEY_GEN (0x1000)
632#define CKM_SKIPJACK_ECB64 (0x1001)
633#define CKM_SKIPJACK_CBC64 (0x1002)
634#define CKM_SKIPJACK_OFB64 (0x1003)
635#define CKM_SKIPJACK_CFB64 (0x1004)
636#define CKM_SKIPJACK_CFB32 (0x1005)
637#define CKM_SKIPJACK_CFB16 (0x1006)
638#define CKM_SKIPJACK_CFB8 (0x1007)
639#define CKM_SKIPJACK_WRAP (0x1008)
640#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009)
641#define CKM_SKIPJACK_RELAYX (0x100a)
642#define CKM_KEA_KEY_PAIR_GEN (0x1010)
643#define CKM_KEA_KEY_DERIVE (0x1011)
644#define CKM_FORTEZZA_TIMESTAMP (0x1020)
645#define CKM_BATON_KEY_GEN (0x1030)
646#define CKM_BATON_ECB128 (0x1031)
647#define CKM_BATON_ECB96 (0x1032)
648#define CKM_BATON_CBC128 (0x1033)
649#define CKM_BATON_COUNTER (0x1034)
650#define CKM_BATON_SHUFFLE (0x1035)
651#define CKM_BATON_WRAP (0x1036)
652#define CKM_ECDSA_KEY_PAIR_GEN (0x1040)
653#define CKM_EC_KEY_PAIR_GEN (0x1040)
654#define CKM_ECDSA (0x1041)
655#define CKM_ECDSA_SHA1 (0x1042)
656#define CKM_ECDH1_DERIVE (0x1050)
657#define CKM_ECDH1_COFACTOR_DERIVE (0x1051)
658#define CKM_ECMQV_DERIVE (0x1052)
659#define CKM_JUNIPER_KEY_GEN (0x1060)
660#define CKM_JUNIPER_ECB128 (0x1061)
661#define CKM_JUNIPER_CBC128 (0x1062)
662#define CKM_JUNIPER_COUNTER (0x1063)
663#define CKM_JUNIPER_SHUFFLE (0x1064)
664#define CKM_JUNIPER_WRAP (0x1065)
665#define CKM_FASTHASH (0x1070)
666#define CKM_AES_KEY_GEN (0x1080)
667#define CKM_AES_ECB (0x1081)
668#define CKM_AES_CBC (0x1082)
669#define CKM_AES_MAC (0x1083)
670#define CKM_AES_MAC_GENERAL (0x1084)
671#define CKM_AES_CBC_PAD (0x1085)
672#define CKM_DSA_PARAMETER_GEN (0x2000)
673#define CKM_DH_PKCS_PARAMETER_GEN (0x2001)
674#define CKM_X9_42_DH_PARAMETER_GEN (0x2002)
675#define CKM_VENDOR_DEFINED ((unsigned long) (1 << 31))
676
677
678struct ck_mechanism
679{
680 ck_mechanism_type_t mechanism;
681 void *parameter;
682 unsigned long parameter_len;
683};
684
685
686struct ck_mechanism_info
687{
688 unsigned long min_key_size;
689 unsigned long max_key_size;
690 ck_flags_t flags;
691};
692
693#define CKF_HW (1 << 0)
694#define CKF_ENCRYPT (1 << 8)
695#define CKF_DECRYPT (1 << 9)
696#define CKF_DIGEST (1 << 10)
697#define CKF_SIGN (1 << 11)
698#define CKF_SIGN_RECOVER (1 << 12)
699#define CKF_VERIFY (1 << 13)
700#define CKF_VERIFY_RECOVER (1 << 14)
701#define CKF_GENERATE (1 << 15)
702#define CKF_GENERATE_KEY_PAIR (1 << 16)
703#define CKF_WRAP (1 << 17)
704#define CKF_UNWRAP (1 << 18)
705#define CKF_DERIVE (1 << 19)
706#define CKF_EXTENSION ((unsigned long) (1 << 31))
707
708
709/* Flags for C_WaitForSlotEvent. */
710#define CKF_DONT_BLOCK (1)
711
712
713typedef unsigned long ck_rv_t;
714
715
716typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session,
717 ck_notification_t event, void *application);
718
719/* Forward reference. */
720struct ck_function_list;
721
722#define _CK_DECLARE_FUNCTION(name, args) \
723typedef ck_rv_t (*CK_ ## name) args; \
724ck_rv_t CK_SPEC name args
725
726_CK_DECLARE_FUNCTION (C_Initialize, (void *init_args));
727_CK_DECLARE_FUNCTION (C_Finalize, (void *reserved));
728_CK_DECLARE_FUNCTION (C_GetInfo, (struct ck_info *info));
729_CK_DECLARE_FUNCTION (C_GetFunctionList,
730 (struct ck_function_list **function_list));
731
732_CK_DECLARE_FUNCTION (C_GetSlotList,
733 (unsigned char token_present, ck_slot_id_t *slot_list,
734 unsigned long *count));
735_CK_DECLARE_FUNCTION (C_GetSlotInfo,
736 (ck_slot_id_t slot_id, struct ck_slot_info *info));
737_CK_DECLARE_FUNCTION (C_GetTokenInfo,
738 (ck_slot_id_t slot_id, struct ck_token_info *info));
739_CK_DECLARE_FUNCTION (C_WaitForSlotEvent,
740 (ck_flags_t flags, ck_slot_id_t *slot, void *reserved));
741_CK_DECLARE_FUNCTION (C_GetMechanismList,
742 (ck_slot_id_t slot_id,
743 ck_mechanism_type_t *mechanism_list,
744 unsigned long *count));
745_CK_DECLARE_FUNCTION (C_GetMechanismInfo,
746 (ck_slot_id_t slot_id, ck_mechanism_type_t type,
747 struct ck_mechanism_info *info));
748_CK_DECLARE_FUNCTION (C_InitToken,
749 (ck_slot_id_t slot_id, unsigned char *pin,
750 unsigned long pin_len, unsigned char *label));
751_CK_DECLARE_FUNCTION (C_InitPIN,
752 (ck_session_handle_t session, unsigned char *pin,
753 unsigned long pin_len));
754_CK_DECLARE_FUNCTION (C_SetPIN,
755 (ck_session_handle_t session, unsigned char *old_pin,
756 unsigned long old_len, unsigned char *new_pin,
757 unsigned long new_len));
758
759_CK_DECLARE_FUNCTION (C_OpenSession,
760 (ck_slot_id_t slot_id, ck_flags_t flags,
761 void *application, ck_notify_t notify,
762 ck_session_handle_t *session));
763_CK_DECLARE_FUNCTION (C_CloseSession, (ck_session_handle_t session));
764_CK_DECLARE_FUNCTION (C_CloseAllSessions, (ck_slot_id_t slot_id));
765_CK_DECLARE_FUNCTION (C_GetSessionInfo,
766 (ck_session_handle_t session,
767 struct ck_session_info *info));
768_CK_DECLARE_FUNCTION (C_GetOperationState,
769 (ck_session_handle_t session,
770 unsigned char *operation_state,
771 unsigned long *operation_state_len));
772_CK_DECLARE_FUNCTION (C_SetOperationState,
773 (ck_session_handle_t session,
774 unsigned char *operation_state,
775 unsigned long operation_state_len,
776 ck_object_handle_t encryption_key,
777 ck_object_handle_t authentiation_key));
778_CK_DECLARE_FUNCTION (C_Login,
779 (ck_session_handle_t session, ck_user_type_t user_type,
780 unsigned char *pin, unsigned long pin_len));
781_CK_DECLARE_FUNCTION (C_Logout, (ck_session_handle_t session));
782
783_CK_DECLARE_FUNCTION (C_CreateObject,
784 (ck_session_handle_t session,
785 struct ck_attribute *templ,
786 unsigned long count, ck_object_handle_t *object));
787_CK_DECLARE_FUNCTION (C_CopyObject,
788 (ck_session_handle_t session, ck_object_handle_t object,
789 struct ck_attribute *templ, unsigned long count,
790 ck_object_handle_t *new_object));
791_CK_DECLARE_FUNCTION (C_DestroyObject,
792 (ck_session_handle_t session,
793 ck_object_handle_t object));
794_CK_DECLARE_FUNCTION (C_GetObjectSize,
795 (ck_session_handle_t session,
796 ck_object_handle_t object,
797 unsigned long *size));
798_CK_DECLARE_FUNCTION (C_GetAttributeValue,
799 (ck_session_handle_t session,
800 ck_object_handle_t object,
801 struct ck_attribute *templ,
802 unsigned long count));
803_CK_DECLARE_FUNCTION (C_SetAttributeValue,
804 (ck_session_handle_t session,
805 ck_object_handle_t object,
806 struct ck_attribute *templ,
807 unsigned long count));
808_CK_DECLARE_FUNCTION (C_FindObjectsInit,
809 (ck_session_handle_t session,
810 struct ck_attribute *templ,
811 unsigned long count));
812_CK_DECLARE_FUNCTION (C_FindObjects,
813 (ck_session_handle_t session,
814 ck_object_handle_t *object,
815 unsigned long max_object_count,
816 unsigned long *object_count));
817_CK_DECLARE_FUNCTION (C_FindObjectsFinal,
818 (ck_session_handle_t session));
819
820_CK_DECLARE_FUNCTION (C_EncryptInit,
821 (ck_session_handle_t session,
822 struct ck_mechanism *mechanism,
823 ck_object_handle_t key));
824_CK_DECLARE_FUNCTION (C_Encrypt,
825 (ck_session_handle_t session,
826 unsigned char *data, unsigned long data_len,
827 unsigned char *encrypted_data,
828 unsigned long *encrypted_data_len));
829_CK_DECLARE_FUNCTION (C_EncryptUpdate,
830 (ck_session_handle_t session,
831 unsigned char *part, unsigned long part_len,
832 unsigned char *encrypted_part,
833 unsigned long *encrypted_part_len));
834_CK_DECLARE_FUNCTION (C_EncryptFinal,
835 (ck_session_handle_t session,
836 unsigned char *last_encrypted_part,
837 unsigned long *last_encrypted_part_len));
838
839_CK_DECLARE_FUNCTION (C_DecryptInit,
840 (ck_session_handle_t session,
841 struct ck_mechanism *mechanism,
842 ck_object_handle_t key));
843_CK_DECLARE_FUNCTION (C_Decrypt,
844 (ck_session_handle_t session,
845 unsigned char *encrypted_data,
846 unsigned long encrypted_data_len,
847 unsigned char *data, unsigned long *data_len));
848_CK_DECLARE_FUNCTION (C_DecryptUpdate,
849 (ck_session_handle_t session,
850 unsigned char *encrypted_part,
851 unsigned long encrypted_part_len,
852 unsigned char *part, unsigned long *part_len));
853_CK_DECLARE_FUNCTION (C_DecryptFinal,
854 (ck_session_handle_t session,
855 unsigned char *last_part,
856 unsigned long *last_part_len));
857
858_CK_DECLARE_FUNCTION (C_DigestInit,
859 (ck_session_handle_t session,
860 struct ck_mechanism *mechanism));
861_CK_DECLARE_FUNCTION (C_Digest,
862 (ck_session_handle_t session,
863 unsigned char *data, unsigned long data_len,
864 unsigned char *digest,
865 unsigned long *digest_len));
866_CK_DECLARE_FUNCTION (C_DigestUpdate,
867 (ck_session_handle_t session,
868 unsigned char *part, unsigned long part_len));
869_CK_DECLARE_FUNCTION (C_DigestKey,
870 (ck_session_handle_t session, ck_object_handle_t key));
871_CK_DECLARE_FUNCTION (C_DigestFinal,
872 (ck_session_handle_t session,
873 unsigned char *digest,
874 unsigned long *digest_len));
875
876_CK_DECLARE_FUNCTION (C_SignInit,
877 (ck_session_handle_t session,
878 struct ck_mechanism *mechanism,
879 ck_object_handle_t key));
880_CK_DECLARE_FUNCTION (C_Sign,
881 (ck_session_handle_t session,
882 unsigned char *data, unsigned long data_len,
883 unsigned char *signature,
884 unsigned long *signature_len));
885_CK_DECLARE_FUNCTION (C_SignUpdate,
886 (ck_session_handle_t session,
887 unsigned char *part, unsigned long part_len));
888_CK_DECLARE_FUNCTION (C_SignFinal,
889 (ck_session_handle_t session,
890 unsigned char *signature,
891 unsigned long *signature_len));
892_CK_DECLARE_FUNCTION (C_SignRecoverInit,
893 (ck_session_handle_t session,
894 struct ck_mechanism *mechanism,
895 ck_object_handle_t key));
896_CK_DECLARE_FUNCTION (C_SignRecover,
897 (ck_session_handle_t session,
898 unsigned char *data, unsigned long data_len,
899 unsigned char *signature,
900 unsigned long *signature_len));
901
902_CK_DECLARE_FUNCTION (C_VerifyInit,
903 (ck_session_handle_t session,
904 struct ck_mechanism *mechanism,
905 ck_object_handle_t key));
906_CK_DECLARE_FUNCTION (C_Verify,
907 (ck_session_handle_t session,
908 unsigned char *data, unsigned long data_len,
909 unsigned char *signature,
910 unsigned long signature_len));
911_CK_DECLARE_FUNCTION (C_VerifyUpdate,
912 (ck_session_handle_t session,
913 unsigned char *part, unsigned long part_len));
914_CK_DECLARE_FUNCTION (C_VerifyFinal,
915 (ck_session_handle_t session,
916 unsigned char *signature,
917 unsigned long signature_len));
918_CK_DECLARE_FUNCTION (C_VerifyRecoverInit,
919 (ck_session_handle_t session,
920 struct ck_mechanism *mechanism,
921 ck_object_handle_t key));
922_CK_DECLARE_FUNCTION (C_VerifyRecover,
923 (ck_session_handle_t session,
924 unsigned char *signature,
925 unsigned long signature_len,
926 unsigned char *data,
927 unsigned long *data_len));
928
929_CK_DECLARE_FUNCTION (C_DigestEncryptUpdate,
930 (ck_session_handle_t session,
931 unsigned char *part, unsigned long part_len,
932 unsigned char *encrypted_part,
933 unsigned long *encrypted_part_len));
934_CK_DECLARE_FUNCTION (C_DecryptDigestUpdate,
935 (ck_session_handle_t session,
936 unsigned char *encrypted_part,
937 unsigned long encrypted_part_len,
938 unsigned char *part,
939 unsigned long *part_len));
940_CK_DECLARE_FUNCTION (C_SignEncryptUpdate,
941 (ck_session_handle_t session,
942 unsigned char *part, unsigned long part_len,
943 unsigned char *encrypted_part,
944 unsigned long *encrypted_part_len));
945_CK_DECLARE_FUNCTION (C_DecryptVerifyUpdate,
946 (ck_session_handle_t session,
947 unsigned char *encrypted_part,
948 unsigned long encrypted_part_len,
949 unsigned char *part,
950 unsigned long *part_len));
951
952_CK_DECLARE_FUNCTION (C_GenerateKey,
953 (ck_session_handle_t session,
954 struct ck_mechanism *mechanism,
955 struct ck_attribute *templ,
956 unsigned long count,
957 ck_object_handle_t *key));
958_CK_DECLARE_FUNCTION (C_GenerateKeyPair,
959 (ck_session_handle_t session,
960 struct ck_mechanism *mechanism,
961 struct ck_attribute *public_key_template,
962 unsigned long public_key_attribute_count,
963 struct ck_attribute *private_key_template,
964 unsigned long private_key_attribute_count,
965 ck_object_handle_t *public_key,
966 ck_object_handle_t *private_key));
967_CK_DECLARE_FUNCTION (C_WrapKey,
968 (ck_session_handle_t session,
969 struct ck_mechanism *mechanism,
970 ck_object_handle_t wrapping_key,
971 ck_object_handle_t key,
972 unsigned char *wrapped_key,
973 unsigned long *wrapped_key_len));
974_CK_DECLARE_FUNCTION (C_UnwrapKey,
975 (ck_session_handle_t session,
976 struct ck_mechanism *mechanism,
977 ck_object_handle_t unwrapping_key,
978 unsigned char *wrapped_key,
979 unsigned long wrapped_key_len,
980 struct ck_attribute *templ,
981 unsigned long attribute_count,
982 ck_object_handle_t *key));
983_CK_DECLARE_FUNCTION (C_DeriveKey,
984 (ck_session_handle_t session,
985 struct ck_mechanism *mechanism,
986 ck_object_handle_t base_key,
987 struct ck_attribute *templ,
988 unsigned long attribute_count,
989 ck_object_handle_t *key));
990
991_CK_DECLARE_FUNCTION (C_SeedRandom,
992 (ck_session_handle_t session, unsigned char *seed,
993 unsigned long seed_len));
994_CK_DECLARE_FUNCTION (C_GenerateRandom,
995 (ck_session_handle_t session,
996 unsigned char *random_data,
997 unsigned long random_len));
998
999_CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session));
1000_CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session));
1001
1002
1003struct ck_function_list
1004{
1005 struct ck_version version;
1006 CK_C_Initialize C_Initialize;
1007 CK_C_Finalize C_Finalize;
1008 CK_C_GetInfo C_GetInfo;
1009 CK_C_GetFunctionList C_GetFunctionList;
1010 CK_C_GetSlotList C_GetSlotList;
1011 CK_C_GetSlotInfo C_GetSlotInfo;
1012 CK_C_GetTokenInfo C_GetTokenInfo;
1013 CK_C_GetMechanismList C_GetMechanismList;
1014 CK_C_GetMechanismInfo C_GetMechanismInfo;
1015 CK_C_InitToken C_InitToken;
1016 CK_C_InitPIN C_InitPIN;
1017 CK_C_SetPIN C_SetPIN;
1018 CK_C_OpenSession C_OpenSession;
1019 CK_C_CloseSession C_CloseSession;
1020 CK_C_CloseAllSessions C_CloseAllSessions;
1021 CK_C_GetSessionInfo C_GetSessionInfo;
1022 CK_C_GetOperationState C_GetOperationState;
1023 CK_C_SetOperationState C_SetOperationState;
1024 CK_C_Login C_Login;
1025 CK_C_Logout C_Logout;
1026 CK_C_CreateObject C_CreateObject;
1027 CK_C_CopyObject C_CopyObject;
1028 CK_C_DestroyObject C_DestroyObject;
1029 CK_C_GetObjectSize C_GetObjectSize;
1030 CK_C_GetAttributeValue C_GetAttributeValue;
1031 CK_C_SetAttributeValue C_SetAttributeValue;
1032 CK_C_FindObjectsInit C_FindObjectsInit;
1033 CK_C_FindObjects C_FindObjects;
1034 CK_C_FindObjectsFinal C_FindObjectsFinal;
1035 CK_C_EncryptInit C_EncryptInit;
1036 CK_C_Encrypt C_Encrypt;
1037 CK_C_EncryptUpdate C_EncryptUpdate;
1038 CK_C_EncryptFinal C_EncryptFinal;
1039 CK_C_DecryptInit C_DecryptInit;
1040 CK_C_Decrypt C_Decrypt;
1041 CK_C_DecryptUpdate C_DecryptUpdate;
1042 CK_C_DecryptFinal C_DecryptFinal;
1043 CK_C_DigestInit C_DigestInit;
1044 CK_C_Digest C_Digest;
1045 CK_C_DigestUpdate C_DigestUpdate;
1046 CK_C_DigestKey C_DigestKey;
1047 CK_C_DigestFinal C_DigestFinal;
1048 CK_C_SignInit C_SignInit;
1049 CK_C_Sign C_Sign;
1050 CK_C_SignUpdate C_SignUpdate;
1051 CK_C_SignFinal C_SignFinal;
1052 CK_C_SignRecoverInit C_SignRecoverInit;
1053 CK_C_SignRecover C_SignRecover;
1054 CK_C_VerifyInit C_VerifyInit;
1055 CK_C_Verify C_Verify;
1056 CK_C_VerifyUpdate C_VerifyUpdate;
1057 CK_C_VerifyFinal C_VerifyFinal;
1058 CK_C_VerifyRecoverInit C_VerifyRecoverInit;
1059 CK_C_VerifyRecover C_VerifyRecover;
1060 CK_C_DigestEncryptUpdate C_DigestEncryptUpdate;
1061 CK_C_DecryptDigestUpdate C_DecryptDigestUpdate;
1062 CK_C_SignEncryptUpdate C_SignEncryptUpdate;
1063 CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate;
1064 CK_C_GenerateKey C_GenerateKey;
1065 CK_C_GenerateKeyPair C_GenerateKeyPair;
1066 CK_C_WrapKey C_WrapKey;
1067 CK_C_UnwrapKey C_UnwrapKey;
1068 CK_C_DeriveKey C_DeriveKey;
1069 CK_C_SeedRandom C_SeedRandom;
1070 CK_C_GenerateRandom C_GenerateRandom;
1071 CK_C_GetFunctionStatus C_GetFunctionStatus;
1072 CK_C_CancelFunction C_CancelFunction;
1073 CK_C_WaitForSlotEvent C_WaitForSlotEvent;
1074};
1075
1076
1077typedef ck_rv_t (*ck_createmutex_t) (void **mutex);
1078typedef ck_rv_t (*ck_destroymutex_t) (void *mutex);
1079typedef ck_rv_t (*ck_lockmutex_t) (void *mutex);
1080typedef ck_rv_t (*ck_unlockmutex_t) (void *mutex);
1081
1082
1083struct ck_c_initialize_args
1084{
1085 ck_createmutex_t create_mutex;
1086 ck_destroymutex_t destroy_mutex;
1087 ck_lockmutex_t lock_mutex;
1088 ck_unlockmutex_t unlock_mutex;
1089 ck_flags_t flags;
1090 void *reserved;
1091};
1092
1093
1094#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1 << 0)
1095#define CKF_OS_LOCKING_OK (1 << 1)
1096
1097#define CKR_OK (0)
1098#define CKR_CANCEL (1)
1099#define CKR_HOST_MEMORY (2)
1100#define CKR_SLOT_ID_INVALID (3)
1101#define CKR_GENERAL_ERROR (5)
1102#define CKR_FUNCTION_FAILED (6)
1103#define CKR_ARGUMENTS_BAD (7)
1104#define CKR_NO_EVENT (8)
1105#define CKR_NEED_TO_CREATE_THREADS (9)
1106#define CKR_CANT_LOCK (0xa)
1107#define CKR_ATTRIBUTE_READ_ONLY (0x10)
1108#define CKR_ATTRIBUTE_SENSITIVE (0x11)
1109#define CKR_ATTRIBUTE_TYPE_INVALID (0x12)
1110#define CKR_ATTRIBUTE_VALUE_INVALID (0x13)
1111#define CKR_DATA_INVALID (0x20)
1112#define CKR_DATA_LEN_RANGE (0x21)
1113#define CKR_DEVICE_ERROR (0x30)
1114#define CKR_DEVICE_MEMORY (0x31)
1115#define CKR_DEVICE_REMOVED (0x32)
1116#define CKR_ENCRYPTED_DATA_INVALID (0x40)
1117#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41)
1118#define CKR_FUNCTION_CANCELED (0x50)
1119#define CKR_FUNCTION_NOT_PARALLEL (0x51)
1120#define CKR_FUNCTION_NOT_SUPPORTED (0x54)
1121#define CKR_KEY_HANDLE_INVALID (0x60)
1122#define CKR_KEY_SIZE_RANGE (0x62)
1123#define CKR_KEY_TYPE_INCONSISTENT (0x63)
1124#define CKR_KEY_NOT_NEEDED (0x64)
1125#define CKR_KEY_CHANGED (0x65)
1126#define CKR_KEY_NEEDED (0x66)
1127#define CKR_KEY_INDIGESTIBLE (0x67)
1128#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68)
1129#define CKR_KEY_NOT_WRAPPABLE (0x69)
1130#define CKR_KEY_UNEXTRACTABLE (0x6a)
1131#define CKR_MECHANISM_INVALID (0x70)
1132#define CKR_MECHANISM_PARAM_INVALID (0x71)
1133#define CKR_OBJECT_HANDLE_INVALID (0x82)
1134#define CKR_OPERATION_ACTIVE (0x90)
1135#define CKR_OPERATION_NOT_INITIALIZED (0x91)
1136#define CKR_PIN_INCORRECT (0xa0)
1137#define CKR_PIN_INVALID (0xa1)
1138#define CKR_PIN_LEN_RANGE (0xa2)
1139#define CKR_PIN_EXPIRED (0xa3)
1140#define CKR_PIN_LOCKED (0xa4)
1141#define CKR_SESSION_CLOSED (0xb0)
1142#define CKR_SESSION_COUNT (0xb1)
1143#define CKR_SESSION_HANDLE_INVALID (0xb3)
1144#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4)
1145#define CKR_SESSION_READ_ONLY (0xb5)
1146#define CKR_SESSION_EXISTS (0xb6)
1147#define CKR_SESSION_READ_ONLY_EXISTS (0xb7)
1148#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8)
1149#define CKR_SIGNATURE_INVALID (0xc0)
1150#define CKR_SIGNATURE_LEN_RANGE (0xc1)
1151#define CKR_TEMPLATE_INCOMPLETE (0xd0)
1152#define CKR_TEMPLATE_INCONSISTENT (0xd1)
1153#define CKR_TOKEN_NOT_PRESENT (0xe0)
1154#define CKR_TOKEN_NOT_RECOGNIZED (0xe1)
1155#define CKR_TOKEN_WRITE_PROTECTED (0xe2)
1156#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0)
1157#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1)
1158#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2)
1159#define CKR_USER_ALREADY_LOGGED_IN (0x100)
1160#define CKR_USER_NOT_LOGGED_IN (0x101)
1161#define CKR_USER_PIN_NOT_INITIALIZED (0x102)
1162#define CKR_USER_TYPE_INVALID (0x103)
1163#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104)
1164#define CKR_USER_TOO_MANY_TYPES (0x105)
1165#define CKR_WRAPPED_KEY_INVALID (0x110)
1166#define CKR_WRAPPED_KEY_LEN_RANGE (0x112)
1167#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113)
1168#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114)
1169#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115)
1170#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120)
1171#define CKR_RANDOM_NO_RNG (0x121)
1172#define CKR_DOMAIN_PARAMS_INVALID (0x130)
1173#define CKR_BUFFER_TOO_SMALL (0x150)
1174#define CKR_SAVED_STATE_INVALID (0x160)
1175#define CKR_INFORMATION_SENSITIVE (0x170)
1176#define CKR_STATE_UNSAVEABLE (0x180)
1177#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190)
1178#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191)
1179#define CKR_MUTEX_BAD (0x1a0)
1180#define CKR_MUTEX_NOT_LOCKED (0x1a1)
1181#define CKR_FUNCTION_REJECTED (0x200)
1182#define CKR_VENDOR_DEFINED ((unsigned long) (1 << 31))
1183
1184
1185
1186/* Compatibility layer. */
1187
1188#ifdef CRYPTOKI_COMPAT
1189
1190#undef CK_DEFINE_FUNCTION
1191#define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name
1192
1193/* For NULL. */
1194#include <stddef.h>
1195
1196typedef unsigned char CK_BYTE;
1197typedef unsigned char CK_CHAR;
1198typedef unsigned char CK_UTF8CHAR;
1199typedef unsigned char CK_BBOOL;
1200typedef unsigned long int CK_ULONG;
1201typedef long int CK_LONG;
1202typedef CK_BYTE *CK_BYTE_PTR;
1203typedef CK_CHAR *CK_CHAR_PTR;
1204typedef CK_UTF8CHAR *CK_UTF8CHAR_PTR;
1205typedef CK_ULONG *CK_ULONG_PTR;
1206typedef void *CK_VOID_PTR;
1207typedef void **CK_VOID_PTR_PTR;
1208#define CK_FALSE 0
1209#define CK_TRUE 1
1210#ifndef CK_DISABLE_TRUE_FALSE
1211#ifndef FALSE
1212#define FALSE 0
1213#endif
1214#ifndef TRUE
1215#define TRUE 1
1216#endif
1217#endif
1218
1219typedef struct ck_version CK_VERSION;
1220typedef struct ck_version *CK_VERSION_PTR;
1221
1222typedef struct ck_info CK_INFO;
1223typedef struct ck_info *CK_INFO_PTR;
1224
1225typedef ck_slot_id_t *CK_SLOT_ID_PTR;
1226
1227typedef struct ck_slot_info CK_SLOT_INFO;
1228typedef struct ck_slot_info *CK_SLOT_INFO_PTR;
1229
1230typedef struct ck_token_info CK_TOKEN_INFO;
1231typedef struct ck_token_info *CK_TOKEN_INFO_PTR;
1232
1233typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR;
1234
1235typedef struct ck_session_info CK_SESSION_INFO;
1236typedef struct ck_session_info *CK_SESSION_INFO_PTR;
1237
1238typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR;
1239
1240typedef ck_object_class_t *CK_OBJECT_CLASS_PTR;
1241
1242typedef struct ck_attribute CK_ATTRIBUTE;
1243typedef struct ck_attribute *CK_ATTRIBUTE_PTR;
1244
1245typedef struct ck_date CK_DATE;
1246typedef struct ck_date *CK_DATE_PTR;
1247
1248typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR;
1249
1250typedef struct ck_mechanism CK_MECHANISM;
1251typedef struct ck_mechanism *CK_MECHANISM_PTR;
1252
1253typedef struct ck_mechanism_info CK_MECHANISM_INFO;
1254typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR;
1255
1256typedef struct ck_function_list CK_FUNCTION_LIST;
1257typedef struct ck_function_list *CK_FUNCTION_LIST_PTR;
1258typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR;
1259
1260typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS;
1261typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR;
1262
1263#define NULL_PTR NULL
1264
1265/* Delete the helper macros defined at the top of the file. */
1266#undef ck_flags_t
1267#undef ck_version
1268
1269#undef ck_info
1270#undef cryptoki_version
1271#undef manufacturer_id
1272#undef library_description
1273#undef library_version
1274
1275#undef ck_notification_t
1276#undef ck_slot_id_t
1277
1278#undef ck_slot_info
1279#undef slot_description
1280#undef hardware_version
1281#undef firmware_version
1282
1283#undef ck_token_info
1284#undef serial_number
1285#undef max_session_count
1286#undef session_count
1287#undef max_rw_session_count
1288#undef rw_session_count
1289#undef max_pin_len
1290#undef min_pin_len
1291#undef total_public_memory
1292#undef free_public_memory
1293#undef total_private_memory
1294#undef free_private_memory
1295#undef utc_time
1296
1297#undef ck_session_handle_t
1298#undef ck_user_type_t
1299#undef ck_state_t
1300
1301#undef ck_session_info
1302#undef slot_id
1303#undef device_error
1304
1305#undef ck_object_handle_t
1306#undef ck_object_class_t
1307#undef ck_hw_feature_type_t
1308#undef ck_key_type_t
1309#undef ck_certificate_type_t
1310#undef ck_attribute_type_t
1311
1312#undef ck_attribute
1313#undef value
1314#undef value_len
1315
1316#undef ck_date
1317
1318#undef ck_mechanism_type_t
1319
1320#undef ck_mechanism
1321#undef parameter
1322#undef parameter_len
1323
1324#undef ck_mechanism_info
1325#undef min_key_size
1326#undef max_key_size
1327
1328#undef ck_rv_t
1329#undef ck_notify_t
1330
1331#undef ck_function_list
1332
1333#undef ck_createmutex_t
1334#undef ck_destroymutex_t
1335#undef ck_lockmutex_t
1336#undef ck_unlockmutex_t
1337
1338#undef ck_c_initialize_args
1339#undef create_mutex
1340#undef destroy_mutex
1341#undef lock_mutex
1342#undef unlock_mutex
1343#undef reserved
1344
1345#endif /* CRYPTOKI_COMPAT */
1346
1347
1348/* System dependencies. */
1349#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32)
1350#pragma pack(pop, cryptoki)
1351#endif
1352
1353#if defined(__cplusplus)
1354}
1355#endif
1356
1357#endif /* PKCS11_H */
diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in
new file mode 100644
index 0000000..0529ef8
--- /dev/null
+++ b/src/versioninfo.rc.in
@@ -0,0 +1,35 @@
1#include <winresrc.h>
2
3VS_VERSION_INFO VERSIONINFO
4 FILEVERSION @LIBP11_LT_CURRENT@,@LIBP11_LT_AGE@,@LIBP11_LT_REVISION@,0
5 PRODUCTVERSION @LIBP11_VERSION_MAJOR@,@LIBP11_VERSION_MINOR@,@LIBP11_VERSION_FIX@,0
6 FILEFLAGSMASK 0x3fL
7#ifdef _DEBUG
8 FILEFLAGS 0x21L
9#else
10 FILEFLAGS 0x20L
11#endif
12 FILEOS 0x40004L
13 FILETYPE 0x1L
14 FILESUBTYPE 0x0L
15BEGIN
16 BLOCK "StringFileInfo"
17 BEGIN
18 BLOCK "040904b0"
19 BEGIN
20 VALUE "Comments", "Provided under the terms of the GNU General Public License (LGPLv2.1+).\0"
21 VALUE "CompanyName", "OpenSC Project\0"
22 VALUE "FileDescription", "PKCS#11 access library\0"
23 VALUE "FileVersion", "@LIBP11_LT_CURRENT@.@LIBP11_LT_AGE@.@LIBP11_LT_REVISION@.0\0"
24 VALUE "InternalName", "@PACKAGE_NAME@\0"
25 VALUE "LegalCopyright", "OpenSC Project\0"
26 VALUE "LegalTrademarks", "\0"
27 VALUE "OriginalFilename", "@PACKAGE_NAME@-@LIBP11_LT_OLDEST@.dll\0"
28 VALUE "PrivateBuild", "\0"
29 VALUE "ProductName", "@PACKAGE_NAME@\0"
30 VALUE "ProductVersion", "@LIBP11_VERSION_MAJOR@,@LIBP11_VERSION_MINOR@,@LIBP11_VERSION_FIX@,0\0"
31 VALUE "SpecialBuild", "\0"
32 END
33 END
34END
35
diff --git a/winconfig.h b/winconfig.h
new file mode 100644
index 0000000..013255c
--- /dev/null
+++ b/winconfig.h
@@ -0,0 +1 @@
/* nothing for now */