summaryrefslogtreecommitdiffstats
path: root/third_party/rust/pkcs11
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/pkcs11')
-rw-r--r--third_party/rust/pkcs11/.cargo-checksum.json1
-rw-r--r--third_party/rust/pkcs11/Cargo.toml39
-rw-r--r--third_party/rust/pkcs11/LICENSE202
-rw-r--r--third_party/rust/pkcs11/NOTICE13
-rw-r--r--third_party/rust/pkcs11/README.md46
-rw-r--r--third_party/rust/pkcs11/rustfmt.toml81
-rw-r--r--third_party/rust/pkcs11/src/errors.rs152
-rw-r--r--third_party/rust/pkcs11/src/functions.rs760
-rw-r--r--third_party/rust/pkcs11/src/lib.rs1298
-rw-r--r--third_party/rust/pkcs11/src/tests.rs1552
-rw-r--r--third_party/rust/pkcs11/src/types.rs2497
11 files changed, 6641 insertions, 0 deletions
diff --git a/third_party/rust/pkcs11/.cargo-checksum.json b/third_party/rust/pkcs11/.cargo-checksum.json
new file mode 100644
index 0000000000..8f86e37c0d
--- /dev/null
+++ b/third_party/rust/pkcs11/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"b04ba4906f065e937aac92197aaa7ec3628f52c0c6277cc27401d571a3d4472c","LICENSE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","NOTICE":"6e0c856925602c18a04e173be3a6e2d812a7ca4501176642a07fec1af97e0eab","README.md":"4f227c9d8a3c07e4b82b2812d3fcc512cdf477a4daf2c9c955f49fb2e94cbab8","rustfmt.toml":"925e9c7b3d6df043a11531da116439cc0d0b0368b682875a8fb0e8229fc7df01","src/errors.rs":"efcc4e8472ee06de82b122017cca4e87898034c98bc9b593110b2a4f8a557e26","src/functions.rs":"1bec1b1ac5c38d3db527880ab5b06005f567a52bba7b98b1ec0fdf64f7d0a68b","src/lib.rs":"3d22aaedf17669d9ca5f50c7ff892e7d874d257369fa40b49ed582409ee94455","src/tests.rs":"b7257ef2bff4321ac03095af9b4015fc9a88d2cddddb94ca8ae8f7516b19e7f1","src/types.rs":"797b99955b4fa30ad373ee435076c6d251978bb6ae724cc9a082020fb8f984fc"},"package":"c20593a99fe08068cbe2b59001527f36021d6ad53ac5f2d8793fcf2fe94015a0"} \ No newline at end of file
diff --git a/third_party/rust/pkcs11/Cargo.toml b/third_party/rust/pkcs11/Cargo.toml
new file mode 100644
index 0000000000..7dbaf28199
--- /dev/null
+++ b/third_party/rust/pkcs11/Cargo.toml
@@ -0,0 +1,39 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "pkcs11"
+version = "0.4.1"
+authors = ["Marcus Heese <marcus.heese@gmail.com>"]
+exclude = ["pkcs11-docs/**"]
+description = "Rust PKCS#11 Library"
+homepage = "https://github.com/mheese/rust-pkcs11"
+keywords = ["pkcs11", "cryptoki"]
+categories = ["external-ffi-bindings", "cryptography", "hardware-support"]
+license = "Apache-2.0"
+repository = "https://github.com/mheese/rust-pkcs11"
+[dependencies.libloading]
+version = "^0.5"
+
+[dependencies.num-bigint]
+version = "^0.2"
+[dev-dependencies.hex]
+version = "^0.3"
+
+[dev-dependencies.num-traits]
+version = "^0.1"
+
+[dev-dependencies.serial_test]
+version = "~0.1"
+
+[dev-dependencies.serial_test_derive]
+version = "~0.1"
diff --git a/third_party/rust/pkcs11/LICENSE b/third_party/rust/pkcs11/LICENSE
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/third_party/rust/pkcs11/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/third_party/rust/pkcs11/NOTICE b/third_party/rust/pkcs11/NOTICE
new file mode 100644
index 0000000000..7b2f807e5a
--- /dev/null
+++ b/third_party/rust/pkcs11/NOTICE
@@ -0,0 +1,13 @@
+Rust PKCS#11 Library
+Copyright 2017 Marcus Heese
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+-------------------------------------------------------------------------------
+This product bundles OASIS PKCS#11 documentation and header files, which are
+available under the OASIS IPR Policy
+
+ [http://www.oasis-open.org/policies-guidelines/ipr].
+
+For details, see pkcs11-docs/. \ No newline at end of file
diff --git a/third_party/rust/pkcs11/README.md b/third_party/rust/pkcs11/README.md
new file mode 100644
index 0000000000..09f552e3aa
--- /dev/null
+++ b/third_party/rust/pkcs11/README.md
@@ -0,0 +1,46 @@
+<!--
+Copyright 2017 Marcus Heese
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+# Rust PKCS#11 Library
+
+This is a library which brings support for PKCS#11 to Rust. It is aiming at having both a very low-level API to map the PKCS#11 functionality to Rust as well as having a higher-level API for more easy usage as well as bringing more safety for programming against PKCS#11.
+
+## Testing
+
+Testing is currently done with [SoftHSM2](https://github.com/opendnssec/SoftHSMv2 "SoftHSM2 Repo"). A trillion thanks to the people at OpenDNSSEC for writing SoftHSM. This makes it possible to develop applications that need to support PKCS#11. I would have no idea what to do without it. (Suggestions are always welcome.)
+
+### Status
+
+Here is a list of the implementation status and plans on what to do next:
+- [x] Dynamic loading of PKCS#11 module (thanks to [libloading](https://github.com/nagisa/rust_libloading "libloading Repo"))
+- [x] Initializing and Dropping PKCS#11 context
+- [x] Implementing Token and PIN Management functions
+- [x] Implementing Session Management functions
+- [x] Implementing Object Management functions
+- [x] Implementing Key Management functions
+- [x] Implementing Encryption/Decryption functions (TODO: tests still missing)
+- [x] Implementing Message Digest functions (TODO: tests still missing)
+- [x] Implementing Signing and MACing (TODO: tests still missing)
+- [x] Implementing Verifying of signatures and MACs (TODO: tests still missing)
+- [x] Implementing Dual-function cryptographic operations (TODO: tests still missing)
+- [x] Implementing Legacy PKCS#11 functions
+- [x] Reorganize code of low-level API (too bloated, which we all know is what PKCS#11 is like)
+- [x] Import the rest of the C header `pkcs11t.h` types into rust
+- [x] Import the rest of the C header `pkcs11f.h` functions into rust
+- [ ] C type constants to string converter functions, and the reverse (maybe part of the high-level API?)
+- [ ] Design and implement high-level API
+- [x] Publish on crates.io (wow, that was easy)
+- [ ] Write and Generate Documentation for Rust docs
+- [ ] Better Testing (lots of repetitive code + we need a testing framework and different SoftHSM versions for different platforms)
diff --git a/third_party/rust/pkcs11/rustfmt.toml b/third_party/rust/pkcs11/rustfmt.toml
new file mode 100644
index 0000000000..5d3f1f575c
--- /dev/null
+++ b/third_party/rust/pkcs11/rustfmt.toml
@@ -0,0 +1,81 @@
+# Copyright 2017 Marcus Heese
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+verbose = false
+disable_all_formatting = false
+skip_children = false
+max_width = 200
+error_on_line_overflow = true
+tab_spaces = 2
+fn_call_width = 200
+struct_lit_width = 18
+struct_variant_width = 35
+force_explicit_abi = true
+newline_style = "Unix"
+fn_brace_style = "SameLineWhere"
+item_brace_style = "SameLineWhere"
+control_style = "Rfc"
+control_brace_style = "AlwaysSameLine"
+impl_empty_single_line = true
+trailing_comma = "Vertical"
+fn_empty_single_line = true
+fn_single_line = false
+fn_return_indent = "WithArgs"
+fn_args_paren_newline = false
+fn_args_density = "Tall"
+fn_args_layout = "Block"
+array_layout = "Block"
+array_width = 60
+type_punctuation_density = "Wide"
+where_style = "Rfc"
+where_density = "CompressedIfEmpty"
+where_layout = "Vertical"
+where_pred_indent = "Visual"
+generics_indent = "Block"
+struct_lit_style = "Block"
+struct_lit_multiline_style = "PreferSingle"
+fn_call_style = "Block"
+report_todo = "Never"
+report_fixme = "Never"
+chain_indent = "Block"
+chain_one_line_max = 100
+chain_split_single_child = false
+reorder_imports = false
+reorder_imports_in_group = false
+reorder_imported_names = false
+single_line_if_else_max_width = 50
+format_strings = false
+force_format_strings = false
+take_source_hints = false
+hard_tabs = false
+wrap_comments = false
+comment_width = 80
+normalize_comments = false
+wrap_match_arms = true
+match_block_trailing_comma = false
+indent_match_arms = true
+closure_block_indent_threshold = 7
+space_before_type_annotation = false
+space_after_type_annotation_colon = true
+space_before_struct_lit_field_colon = false
+space_after_struct_lit_field_colon = true
+space_before_bound = false
+space_after_bound_colon = true
+spaces_around_ranges = false
+spaces_within_angle_brackets = false
+spaces_within_square_brackets = false
+spaces_within_parens = false
+use_try_shorthand = false
+write_mode = "Replace"
+condense_wildcard_suffixes = false
+combine_control_expr = true
diff --git a/third_party/rust/pkcs11/src/errors.rs b/third_party/rust/pkcs11/src/errors.rs
new file mode 100644
index 0000000000..fbb45d220d
--- /dev/null
+++ b/third_party/rust/pkcs11/src/errors.rs
@@ -0,0 +1,152 @@
+// Copyright 2017 Marcus Heese
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use std;
+use types::*;
+
+#[derive(Debug)]
+pub enum Error {
+ Io(std::io::Error),
+ Module(&'static str),
+ InvalidInput(&'static str),
+ Pkcs11(CK_RV),
+}
+
+impl From<std::io::Error> for Error {
+ fn from(err: std::io::Error) -> Error {
+ Error::Io(err)
+ }
+}
+
+impl std::fmt::Display for Error {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ match *self {
+ Error::Io(ref err) => write!(f, "IO: {}", err),
+ Error::Module(ref err) => write!(f, "PKCS#11 Module: {}", err),
+ Error::InvalidInput(ref err) => write!(f, "PKCS#11 Invalid Input: {}", err),
+ Error::Pkcs11(ref err) => write!(f, "PKCS#11: {} (0x{:x})", strerror(*err), err),
+ }
+ }
+}
+
+impl std::error::Error for Error {
+ fn cause(&self) -> Option<&std::error::Error> {
+ if let Error::Io(ref err) = self {
+ Some(err)
+ } else {
+ None
+ }
+ }
+}
+
+fn strerror(err: CK_RV) -> &'static str {
+ match err {
+ CKR_OK => "CKR_OK",
+ CKR_CANCEL => "CKR_CANCEL",
+ CKR_HOST_MEMORY => "CKR_HOST_MEMORY",
+ CKR_SLOT_ID_INVALID => "CKR_SLOT_ID_INVALID",
+ CKR_GENERAL_ERROR => "CKR_GENERAL_ERROR",
+ CKR_FUNCTION_FAILED => "CKR_FUNCTION_FAILED",
+ CKR_ARGUMENTS_BAD => "CKR_ARGUMENTS_BAD",
+ CKR_NO_EVENT => "CKR_NO_EVENT",
+ CKR_NEED_TO_CREATE_THREADS => "CKR_NEED_TO_CREATE_THREADS",
+ CKR_CANT_LOCK => "CKR_CANT_LOCK",
+ CKR_ATTRIBUTE_READ_ONLY => "CKR_ATTRIBUTE_READ_ONLY",
+ CKR_ATTRIBUTE_SENSITIVE => "CKR_ATTRIBUTE_SENSITIVE",
+ CKR_ATTRIBUTE_TYPE_INVALID => "CKR_ATTRIBUTE_TYPE_INVALID",
+ CKR_ATTRIBUTE_VALUE_INVALID => "CKR_ATTRIBUTE_VALUE_INVALID",
+ CKR_ACTION_PROHIBITED => "CKR_ACTION_PROHIBITED",
+ CKR_DATA_INVALID => "CKR_DATA_INVALID",
+ CKR_DATA_LEN_RANGE => "CKR_DATA_LEN_RANGE",
+ CKR_DEVICE_ERROR => "CKR_DEVICE_ERROR",
+ CKR_DEVICE_MEMORY => "CKR_DEVICE_MEMORY",
+ CKR_DEVICE_REMOVED => "CKR_DEVICE_REMOVED",
+ CKR_ENCRYPTED_DATA_INVALID => "CKR_ENCRYPTED_DATA_INVALID",
+ CKR_ENCRYPTED_DATA_LEN_RANGE => "CKR_ENCRYPTED_DATA_LEN_RANGE",
+ CKR_FUNCTION_CANCELED => "CKR_FUNCTION_CANCELED",
+ CKR_FUNCTION_NOT_PARALLEL => "CKR_FUNCTION_NOT_PARALLEL",
+ CKR_FUNCTION_NOT_SUPPORTED => "CKR_FUNCTION_NOT_SUPPORTED",
+ CKR_KEY_HANDLE_INVALID => "CKR_KEY_HANDLE_INVALID",
+ CKR_KEY_SIZE_RANGE => "CKR_KEY_SIZE_RANGE",
+ CKR_KEY_TYPE_INCONSISTENT => "CKR_KEY_TYPE_INCONSISTENT",
+ CKR_KEY_NOT_NEEDED => "CKR_KEY_NOT_NEEDED",
+ CKR_KEY_CHANGED => "CKR_KEY_CHANGED",
+ CKR_KEY_NEEDED => "CKR_KEY_NEEDED",
+ CKR_KEY_INDIGESTIBLE => "CKR_KEY_INDIGESTIBLE",
+ CKR_KEY_FUNCTION_NOT_PERMITTED => "CKR_KEY_FUNCTION_NOT_PERMITTED",
+ CKR_KEY_NOT_WRAPPABLE => "CKR_KEY_NOT_WRAPPABLE",
+ CKR_KEY_UNEXTRACTABLE => "CKR_KEY_UNEXTRACTABLE",
+ CKR_MECHANISM_INVALID => "CKR_MECHANISM_INVALID",
+ CKR_MECHANISM_PARAM_INVALID => "CKR_MECHANISM_PARAM_INVALID",
+ CKR_OBJECT_HANDLE_INVALID => "CKR_OBJECT_HANDLE_INVALID",
+ CKR_OPERATION_ACTIVE => "CKR_OPERATION_ACTIVE",
+ CKR_OPERATION_NOT_INITIALIZED => "CKR_OPERATION_NOT_INITIALIZED",
+ CKR_PIN_INCORRECT => "CKR_PIN_INCORRECT",
+ CKR_PIN_INVALID => "CKR_PIN_INVALID",
+ CKR_PIN_LEN_RANGE => "CKR_PIN_LEN_RANGE",
+ CKR_PIN_EXPIRED => "CKR_PIN_EXPIRED",
+ CKR_PIN_LOCKED => "CKR_PIN_LOCKED",
+ CKR_SESSION_CLOSED => "CKR_SESSION_CLOSED",
+ CKR_SESSION_COUNT => "CKR_SESSION_COUNT",
+ CKR_SESSION_HANDLE_INVALID => "CKR_SESSION_HANDLE_INVALID",
+ CKR_SESSION_PARALLEL_NOT_SUPPORTED => "CKR_SESSION_PARALLEL_NOT_SUPPORTED",
+ CKR_SESSION_READ_ONLY => "CKR_SESSION_READ_ONLY",
+ CKR_SESSION_EXISTS => "CKR_SESSION_EXISTS",
+ CKR_SESSION_READ_ONLY_EXISTS => "CKR_SESSION_READ_ONLY_EXISTS",
+ CKR_SESSION_READ_WRITE_SO_EXISTS => "CKR_SESSION_READ_WRITE_SO_EXISTS",
+ CKR_SIGNATURE_INVALID => "CKR_SIGNATURE_INVALID",
+ CKR_SIGNATURE_LEN_RANGE => "CKR_SIGNATURE_LEN_RANGE",
+ CKR_TEMPLATE_INCOMPLETE => "CKR_TEMPLATE_INCOMPLETE",
+ CKR_TEMPLATE_INCONSISTENT => "CKR_TEMPLATE_INCONSISTENT",
+ CKR_TOKEN_NOT_PRESENT => "CKR_TOKEN_NOT_PRESENT",
+ CKR_TOKEN_NOT_RECOGNIZED => "CKR_TOKEN_NOT_RECOGNIZED",
+ CKR_TOKEN_WRITE_PROTECTED => "CKR_TOKEN_WRITE_PROTECTED",
+ CKR_UNWRAPPING_KEY_HANDLE_INVALID => "CKR_UNWRAPPING_KEY_HANDLE_INVALID",
+ CKR_UNWRAPPING_KEY_SIZE_RANGE => "CKR_UNWRAPPING_KEY_SIZE_RANGE",
+ CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT => "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT",
+ CKR_USER_ALREADY_LOGGED_IN => "CKR_USER_ALREADY_LOGGED_IN",
+ CKR_USER_NOT_LOGGED_IN => "CKR_USER_NOT_LOGGED_IN",
+ CKR_USER_PIN_NOT_INITIALIZED => "CKR_USER_PIN_NOT_INITIALIZED",
+ CKR_USER_TYPE_INVALID => "CKR_USER_TYPE_INVALID",
+ CKR_USER_ANOTHER_ALREADY_LOGGED_IN => "CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
+ CKR_USER_TOO_MANY_TYPES => "CKR_USER_TOO_MANY_TYPES",
+ CKR_WRAPPED_KEY_INVALID => "CKR_WRAPPED_KEY_INVALID",
+ CKR_WRAPPED_KEY_LEN_RANGE => "CKR_WRAPPED_KEY_LEN_RANGE",
+ CKR_WRAPPING_KEY_HANDLE_INVALID => "CKR_WRAPPING_KEY_HANDLE_INVALID",
+ CKR_WRAPPING_KEY_SIZE_RANGE => "CKR_WRAPPING_KEY_SIZE_RANGE",
+ CKR_WRAPPING_KEY_TYPE_INCONSISTENT => "CKR_WRAPPING_KEY_TYPE_INCONSISTENT",
+ CKR_RANDOM_SEED_NOT_SUPPORTED => "CKR_RANDOM_SEED_NOT_SUPPORTED",
+ CKR_RANDOM_NO_RNG => "CKR_RANDOM_NO_RNG",
+ CKR_DOMAIN_PARAMS_INVALID => "CKR_DOMAIN_PARAMS_INVALID",
+ CKR_CURVE_NOT_SUPPORTED => "CKR_CURVE_NOT_SUPPORTED",
+ CKR_BUFFER_TOO_SMALL => "CKR_BUFFER_TOO_SMALL",
+ CKR_SAVED_STATE_INVALID => "CKR_SAVED_STATE_INVALID",
+ CKR_INFORMATION_SENSITIVE => "CKR_INFORMATION_SENSITIVE",
+ CKR_STATE_UNSAVEABLE => "CKR_STATE_UNSAVEABLE",
+ CKR_CRYPTOKI_NOT_INITIALIZED => "CKR_CRYPTOKI_NOT_INITIALIZED",
+ CKR_CRYPTOKI_ALREADY_INITIALIZED => "CKR_CRYPTOKI_ALREADY_INITIALIZED",
+ CKR_MUTEX_BAD => "CKR_MUTEX_BAD",
+ CKR_MUTEX_NOT_LOCKED => "CKR_MUTEX_NOT_LOCKED",
+ CKR_NEW_PIN_MODE => "CKR_NEW_PIN_MODE",
+ CKR_NEXT_OTP => "CKR_NEXT_OTP",
+ CKR_EXCEEDED_MAX_ITERATIONS => "CKR_EXCEEDED_MAX_ITERATIONS",
+ CKR_FIPS_SELF_TEST_FAILED => "CKR_FIPS_SELF_TEST_FAILED",
+ CKR_LIBRARY_LOAD_FAILED => "CKR_LIBRARY_LOAD_FAILED",
+ CKR_PIN_TOO_WEAK => "CKR_PIN_TOO_WEAK",
+ CKR_PUBLIC_KEY_INVALID => "CKR_PUBLIC_KEY_INVALID",
+ CKR_FUNCTION_REJECTED => "CKR_FUNCTION_REJECTED",
+ CKR_VENDOR_DEFINED => "CKR_VENDOR_DEFINED",
+ _ => "unknown",
+ }
+}
diff --git a/third_party/rust/pkcs11/src/functions.rs b/third_party/rust/pkcs11/src/functions.rs
new file mode 100644
index 0000000000..b1a9286210
--- /dev/null
+++ b/third_party/rust/pkcs11/src/functions.rs
@@ -0,0 +1,760 @@
+// Copyright 2017 Marcus Heese
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#![allow(non_camel_case_types, non_snake_case)]
+
+use types::*;
+
+/// `C_Initialize` initializes the Cryptoki library.
+///
+/// # Function Parameters
+///
+/// * `pInitArgs`: if this is not NULL_PTR, it gets cast to CK_C_INITIALIZE_ARGS_PTR and dereferenced
+///
+pub type C_Initialize = extern "C" fn(pInitArgs: CK_C_INITIALIZE_ARGS_PTR) -> CK_RV;
+
+/// `C_Finalize` indicates that an application is done with the Cryptoki library.
+///
+/// # Function Parameters
+///
+/// * `pReserved`: reserved. Should be NULL_PTR
+///
+pub type C_Finalize = extern "C" fn(pReserved: CK_VOID_PTR) -> CK_RV;
+
+/// `C_GetInfo` returns general information about Cryptoki.
+///
+/// # Function Parameters
+///
+/// * `pInfo`: location that receives information
+///
+pub type C_GetInfo = extern "C" fn(pInfo: CK_INFO_PTR) -> CK_RV;
+
+/// `C_GetFunctionList` returns the function list.
+///
+/// # Function Parameters
+///
+/// * `ppFunctionList`: receives pointer to function list
+///
+pub type C_GetFunctionList = extern "C" fn(ppFunctionList: CK_FUNCTION_LIST_PTR_PTR) -> CK_RV;
+
+/// `C_GetSlotList` obtains a list of slots in the system.
+///
+/// # Function Parameters
+///
+/// * `tokenPresent`: only slots with tokens
+/// * `pSlotList`: receives array of slot IDs
+/// * `pulCount`: receives number of slots
+///
+pub type C_GetSlotList = extern "C" fn(tokenPresent: CK_BBOOL, pSlotList: CK_SLOT_ID_PTR, pulCount: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_GetSlotInfo` obtains information about a particular slot in the system.
+///
+/// # Function Parameters
+///
+/// * `slotID`: the ID of the slot
+/// * `pInfo`: receives the slot information
+///
+pub type C_GetSlotInfo = extern "C" fn(slotID: CK_SLOT_ID, pInfo: CK_SLOT_INFO_PTR) -> CK_RV;
+
+/// `C_GetTokenInfo` obtains information about a particular token in the system.
+///
+/// # Function Parameters
+///
+/// * `slotID`: ID of the token's slot
+/// * `pInfo`: receives the token information
+///
+pub type C_GetTokenInfo = extern "C" fn(slotID: CK_SLOT_ID, pInfo: CK_TOKEN_INFO_PTR) -> CK_RV;
+
+/// `C_GetMechanismList` obtains a list of mechanism types supported by a token.
+///
+/// # Function Parameters
+///
+/// * `slotID`: ID of token's slot
+/// * `pMechanismList`: gets mech. array
+/// * `pulCount`: gets # of mechs.
+///
+pub type C_GetMechanismList = extern "C" fn(slotID: CK_SLOT_ID, pMechanismList: CK_MECHANISM_TYPE_PTR, pulCount: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_GetMechanismInfo` obtains information about a particular mechanism possibly supported by a token.
+///
+/// # Function Parameters
+///
+/// * `slotID`: ID of the token's slot
+/// * `mechType`: type of mechanism
+/// * `pInfo`: receives mechanism info
+///
+pub type C_GetMechanismInfo = extern "C" fn(slotID: CK_SLOT_ID, mechType: CK_MECHANISM_TYPE, pInfo: CK_MECHANISM_INFO_PTR) -> CK_RV;
+
+/// `C_InitToken` initializes a token.
+///
+/// # Function Parameters
+///
+/// * `slotID`: ID of the token's slot
+/// * `pPin`: the SO's initial PIN
+/// * `ulPinLen`: length in bytes of the PIN
+/// * `pLabel`: 32-byte token label (blank padded)
+///
+pub type C_InitToken = extern "C" fn(slotID: CK_SLOT_ID, pPin: CK_UTF8CHAR_PTR, ulPinLen: CK_ULONG, pLabel: CK_UTF8CHAR_PTR) -> CK_RV;
+
+/// `C_InitPIN` initializes the normal user's PIN.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pPin`: the normal user's PIN
+/// * `ulPinLen`: length in bytes of the PIN
+///
+pub type C_InitPIN = extern "C" fn(hSession: CK_SESSION_HANDLE, pPin: CK_UTF8CHAR_PTR, ulPinLen: CK_ULONG) -> CK_RV;
+
+/// `C_SetPIN` modifies the PIN of the user who is logged in.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pOldPin`: the old PIN
+/// * `ulOldLen`: length of the old PIN
+/// * `pNewPin`: the new PIN
+/// * `ulNewLen`: length of the new PIN
+///
+pub type C_SetPIN = extern "C" fn(hSession: CK_SESSION_HANDLE, pOldPin: CK_UTF8CHAR_PTR, ulOldLen: CK_ULONG, pNewPin: CK_UTF8CHAR_PTR, ulNewLen: CK_ULONG) -> CK_RV;
+
+/// `C_OpenSession` opens a session between an application and a token.
+///
+/// # Function Parameters
+///
+/// * `slotID`: the slot's ID
+/// * `flags`: from CK_SESSION_INFO
+/// * `pApplication`: passed to callback
+/// * `Notify`: callback function
+/// * `phSession`: gets session handle
+///
+pub type C_OpenSession = extern "C" fn(slotID: CK_SLOT_ID, flags: CK_FLAGS, pApplication: CK_VOID_PTR, Notify: CK_NOTIFY, phSession: CK_SESSION_HANDLE_PTR) -> CK_RV;
+
+/// `C_CloseSession` closes a session between an application and a token.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+///
+pub type C_CloseSession = extern "C" fn(hSession: CK_SESSION_HANDLE) -> CK_RV;
+
+/// `C_CloseAllSessions` closes all sessions with a token.
+///
+/// # Function Parameters
+///
+/// * `slotID`: the token's slot
+///
+pub type C_CloseAllSessions = extern "C" fn(slotID: CK_SLOT_ID) -> CK_RV;
+
+/// `C_GetSessionInfo` obtains information about the session.
+///
+/// # Function Paramters
+///
+/// * `hSession`: the session's handle
+/// * `pInfo`: receives session info
+///
+pub type C_GetSessionInfo = extern "C" fn(hSession: CK_SESSION_HANDLE, pInfo: CK_SESSION_INFO_PTR) -> CK_RV;
+
+/// `C_GetOperationState` obtains the state of the cryptographic operation in a session.
+///
+/// # Function Paramters
+///
+/// * `hSession`: session's handle
+/// * `pOperationState`: gets state
+/// * `pulOperationStateLen`: gets state length
+///
+pub type C_GetOperationState = extern "C" fn(hSession: CK_SESSION_HANDLE, pOperationState: CK_BYTE_PTR, pulOperationStateLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_SetOperationState` restores the state of the cryptographic operation in a session.
+///
+/// # Function Paramters
+///
+/// * `hSession`: session's handle
+/// * `pOperationState`: holds state
+/// * `ulOperationStateLen`: holds state length
+/// * `hEncryptionKey`: en/decryption key
+/// * `hAuthenticationKey`: sign/verify key
+///
+pub type C_SetOperationState = extern "C" fn(
+ hSession: CK_SESSION_HANDLE,
+ pOperationState: CK_BYTE_PTR,
+ ulOperationStateLen: CK_ULONG,
+ hEncryptionKey: CK_OBJECT_HANDLE,
+ hAuthenticationKey: CK_OBJECT_HANDLE,
+) -> CK_RV;
+
+/// `C_Login` logs a user into a token.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `userType`: the user type
+/// * `pPin`: the user's PIN
+/// * `ulPinLen`: the length of the PIN
+///
+pub type C_Login = extern "C" fn(hSession: CK_SESSION_HANDLE, userType: CK_USER_TYPE, pPin: CK_UTF8CHAR_PTR, ulPinLen: CK_ULONG) -> CK_RV;
+
+/// `C_Logout` logs a user out from a token.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+pub type C_Logout = extern "C" fn(hSession: CK_SESSION_HANDLE) -> CK_RV;
+
+/// `C_CreateObject` creates a new object.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pTemplate`: the object's template
+/// * `ulCount`: attributes in template
+/// * `phObject`: gets new object's handle.
+///
+pub type C_CreateObject = extern "C" fn(hSession: CK_SESSION_HANDLE, pTemplate: CK_ATTRIBUTE_PTR, ulCount: CK_ULONG, phObject: CK_OBJECT_HANDLE_PTR) -> CK_RV;
+
+/// `C_CopyObject` copies an object, creating a new object for the copy.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `hObject`: the object's handle
+/// * `pTemplate`: template for new object
+/// * `ulCount`: attributes in template
+/// * `phNewObject`: receives handle of copy
+///
+pub type C_CopyObject = extern "C" fn(hSession: CK_SESSION_HANDLE, hObject: CK_OBJECT_HANDLE, pTemplate: CK_ATTRIBUTE_PTR, ulCount: CK_ULONG, phNewObject: CK_OBJECT_HANDLE_PTR) -> CK_RV;
+
+/// `C_DestroyObject` destroys an object.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `hObject`: the object's handle
+///
+pub type C_DestroyObject = extern "C" fn(hSession: CK_SESSION_HANDLE, hObject: CK_OBJECT_HANDLE) -> CK_RV;
+
+/// `C_GetObjectSize` gets the size of an object in bytes.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `hObject`: the object's handle
+/// * `pulSize`: receives size of object
+///
+pub type C_GetObjectSize = extern "C" fn(hSession: CK_SESSION_HANDLE, hObject: CK_OBJECT_HANDLE, pulSize: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_GetAttributeValue` obtains the value of one or more object attributes.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `hObject`: the object's handle
+/// * `pTemplate`: specifies attrs; gets vals
+/// * `ulCount`: attributes in template
+///
+pub type C_GetAttributeValue = extern "C" fn(hSession: CK_SESSION_HANDLE, hObject: CK_OBJECT_HANDLE, pTemplate: CK_ATTRIBUTE_PTR, ulCount: CK_ULONG) -> CK_RV;
+
+/// `C_SetAttributeValue` modifies the value of one or more object attributes.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `hObject`: the object's handle
+/// * `pTemplate`: specifies attrs and values
+/// * `ulCount`: attributes in template
+///
+pub type C_SetAttributeValue = extern "C" fn(hSession: CK_SESSION_HANDLE, hObject: CK_OBJECT_HANDLE, pTemplate: CK_ATTRIBUTE_PTR, ulCount: CK_ULONG) -> CK_RV;
+
+/// `C_FindObjectsInit` initializes a search for token and session objects that match a template.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pTemplate`: attribute values to match
+/// * `ulCount`: attrs in search template
+///
+pub type C_FindObjectsInit = extern "C" fn(hSession: CK_SESSION_HANDLE, pTemplate: CK_ATTRIBUTE_PTR, ulCount: CK_ULONG) -> CK_RV;
+
+/// `C_FindObjects` continues a search for token and session objects that match a template, obtaining additional object handles.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `phObject`: gets obj. handles
+/// * `ulMaxObjectCount`: max handles to get
+/// * `pulObjectCount`: actual # returned
+///
+pub type C_FindObjects = extern "C" fn(hSession: CK_SESSION_HANDLE, phObject: CK_OBJECT_HANDLE_PTR, ulMaxObjectCount: CK_ULONG, pulObjectCount: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_FindObjectsFinal` finishes a search for token and session objects.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+///
+pub type C_FindObjectsFinal = extern "C" fn(hSession: CK_SESSION_HANDLE) -> CK_RV;
+
+/// `C_EncryptInit` initializes an encryption operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pMechanism`: the encryption mechanism
+/// * `hKey`: handle of encryption key
+///
+pub type C_EncryptInit = extern "C" fn(hSession: CK_SESSION_HANDLE, pMechanism: CK_MECHANISM_PTR, hKey: CK_OBJECT_HANDLE) -> CK_RV;
+
+/// `C_Encrypt` encrypts single-part data.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `pData`: the plaintext data
+/// * `ulDataLen`: bytes of plaintext
+/// * `pEncryptedData`: gets ciphertext
+/// * `pulEncryptedDataLen`: gets c-text size
+///
+pub type C_Encrypt = extern "C" fn(hSession: CK_SESSION_HANDLE, pData: CK_BYTE_PTR, ulDataLen: CK_ULONG, pEncryptedData: CK_BYTE_PTR, pulEncryptedDataLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_EncryptUpdate` continues a multiple-part encryption operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `pPart`: the plaintext data
+/// * `ulPartLen`: plaintext data len
+/// * `pEncryptedPart`: gets ciphertext
+/// * `pulEncryptedPartLen`: gets c-text size
+///
+pub type C_EncryptUpdate = extern "C" fn(hSession: CK_SESSION_HANDLE, pPart: CK_BYTE_PTR, ulPartLen: CK_ULONG, pEncryptedPart: CK_BYTE_PTR, pulEncryptedPartLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_EncryptFinal` finishes a multiple-part encryption operation
+///
+/// # Function Parameters
+///
+/// * `hSession`: session handle
+/// * `pLastEncryptedPart` last c-text
+/// * `pulLastEncryptedPartLen`: gets last size
+///
+pub type C_EncryptFinal = extern "C" fn(hSession: CK_SESSION_HANDLE, pLastEncryptedPart: CK_BYTE_PTR, pulLastEncryptedPartLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_DecryptInit` initializes a decryption operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pMechanism`: the decryption mechanism
+/// * `hKey`: handle of decryption key
+///
+pub type C_DecryptInit = extern "C" fn(hSession: CK_SESSION_HANDLE, pMechanism: CK_MECHANISM_PTR, hKey: CK_OBJECT_HANDLE) -> CK_RV;
+
+/// `C_Decrypt` decrypts encrypted data in a single part.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `pEncryptedData`: ciphertext
+/// * `ulEncryptedDataLen`: ciphertext length
+/// * `pData`: gets plaintext
+/// * `pulDataLen`: gets p-text size
+///
+pub type C_Decrypt = extern "C" fn(hSession: CK_SESSION_HANDLE, pEncryptedData: CK_BYTE_PTR, ulEncryptedDataLen: CK_ULONG, pData: CK_BYTE_PTR, pulDataLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_DecryptUpdate` continues a multiple-part decryption operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `pEncryptedPart`: encrypted data
+/// * `ulEncryptedPartLen`: input length
+/// * `pPart`: gets plaintext
+/// * `pulPartLen`: p-text size
+///
+pub type C_DecryptUpdate = extern "C" fn(hSession: CK_SESSION_HANDLE, pEncryptedPart: CK_BYTE_PTR, ulEncryptedPartLen: CK_ULONG, pPart: CK_BYTE_PTR, pulPartLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_DecryptFinal` finishes a multiple-part decryption operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pLastPart`: gets plaintext
+/// * `pulLastPartLen`: p-text size
+///
+pub type C_DecryptFinal = extern "C" fn(hSession: CK_SESSION_HANDLE, pLastPart: CK_BYTE_PTR, pulLastPartLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_DigestInit` initializes a message-digesting operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pMechanism`: the digesting mechanism
+///
+pub type C_DigestInit = extern "C" fn(hSession: CK_SESSION_HANDLE, pMechanism: CK_MECHANISM_PTR) -> CK_RV;
+
+/// `C_Digest` digests data in a single part.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pData`: data to be digested
+/// * `ulDataLen`: bytes of data to digest
+/// * `pDigest`: gets the message digest
+/// * `pulDigestLen`: gets digest length
+///
+pub type C_Digest = extern "C" fn(hSession: CK_SESSION_HANDLE, pData: CK_BYTE_PTR, ulDataLen: CK_ULONG, pDigest: CK_BYTE_PTR, pulDigestLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_DigestUpdate` continues a multiple-part message-digesting operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pPart`: data to be digested
+/// * `ulPartLen`: bytes of data to be digested
+///
+pub type C_DigestUpdate = extern "C" fn(hSession: CK_SESSION_HANDLE, pPart: CK_BYTE_PTR, ulPartLen: CK_ULONG) -> CK_RV;
+
+/// `C_DigestKey` continues a multi-part message-digesting operation, by digesting the value of a secret key as part of the data already digested.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `hKey`: secret key to digest
+pub type C_DigestKey = extern "C" fn(hSession: CK_SESSION_HANDLE, hKey: CK_OBJECT_HANDLE) -> CK_RV;
+
+/// `C_DigestFinal` finishes a multiple-part message-digesting operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pDigest`: gets the message digest
+/// * `pulDigestLen`: gets byte count of digest
+///
+pub type C_DigestFinal = extern "C" fn(hSession: CK_SESSION_HANDLE, pDigest: CK_BYTE_PTR, pulDigestLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_SignInit` initializes a signature (private key encryption) operation, where the signature is (will be) an appendix to the data, and plaintext cannot be recovered from the signature.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pMechanism`: the signature mechanism
+/// * `hKey`: handle of signature key
+///
+pub type C_SignInit = extern "C" fn(hSession: CK_SESSION_HANDLE, pMechanism: CK_MECHANISM_PTR, hKey: CK_OBJECT_HANDLE) -> CK_RV;
+
+/// `C_Sign` signs (encrypts with private key) data in a single part, where the signature is (will be) an appendix to the data, and plaintext cannot be recovered from the signature.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pData`: the data to sign
+/// * `ulDataLen`: count of bytes to sign
+/// * `pSignature`: gets the signature
+/// * `pulSignatureLen`: gets signature length
+///
+pub type C_Sign = extern "C" fn(hSession: CK_SESSION_HANDLE, pData: CK_BYTE_PTR, ulDataLen: CK_ULONG, pSignature: CK_BYTE_PTR, pulSignatureLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_SignUpdate` continues a multiple-part signature operation, where the signature is (will be) an appendix to the data, and plaintext cannot be recovered from the signature.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pPart`: the data to sign
+/// * `ulPartLen`: count of bytes to sign
+///
+pub type C_SignUpdate = extern "C" fn(hSession: CK_SESSION_HANDLE, pPart: CK_BYTE_PTR, ulPartLen: CK_ULONG) -> CK_RV;
+
+/// `C_SignFinal` finishes a multiple-part signature operation, returning the signature.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pSignature`: gets the signature
+/// * `pulSignatureLen`: gets signature length
+///
+pub type C_SignFinal = extern "C" fn(hSession: CK_SESSION_HANDLE, pSignature: CK_BYTE_PTR, pulSignatureLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_SignRecoverInit` initializes a signature operation, where the data can be recovered from the signature.
+/// `hSession`: the session's handle
+/// `pMechanism`: the signature mechanism
+/// `hKey`: handle of the signature key
+pub type C_SignRecoverInit = extern "C" fn(hSession: CK_SESSION_HANDLE, pMechanism: CK_MECHANISM_PTR, hKey: CK_OBJECT_HANDLE) -> CK_RV;
+
+/// `C_SignRecover` signs data in a single operation, where the data can be recovered from the signature.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pData`: the data to sign
+/// * `ulDataLen`: count of bytes to sign
+/// * `pSignature`: gets the signature
+/// * `pulSignatureLen`: gets signature length
+///
+pub type C_SignRecover = extern "C" fn(hSession: CK_SESSION_HANDLE, pData: CK_BYTE_PTR, ulDataLen: CK_ULONG, pSignature: CK_BYTE_PTR, pulSignatureLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_VerifyInit` initializes a verification operation, where the signature is an appendix to the data, and plaintext cannot cannot be recovered from the signature (e.g. DSA).
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pMechanism`: the verification mechanism
+/// * `hKey`: verification key
+///
+pub type C_VerifyInit = extern "C" fn(hSession: CK_SESSION_HANDLE, pMechanism: CK_MECHANISM_PTR, hKey: CK_OBJECT_HANDLE) -> CK_RV;
+
+/// `C_Verify` verifies a signature in a single-part operation, where the signature is an appendix to the data, and plaintext cannot be recovered from the signature.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pData`: signed data
+/// * `ulDataLen`: length of signed data
+/// * `pSignature`: signature
+/// * `ulSignatureLen`: signature length
+///
+pub type C_Verify = extern "C" fn(hSession: CK_SESSION_HANDLE, pData: CK_BYTE_PTR, ulDataLen: CK_ULONG, pSignature: CK_BYTE_PTR, ulSignatureLen: CK_ULONG) -> CK_RV;
+
+/// `C_VerifyUpdate` continues a multiple-part verification operation, where the signature is an appendix to the data, and plaintext cannot be recovered from the signature.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pPart`: signed data
+/// * `ulPartLen`: length of signed data
+///
+pub type C_VerifyUpdate = extern "C" fn(hSession: CK_SESSION_HANDLE, pPart: CK_BYTE_PTR, ulPartLen: CK_ULONG) -> CK_RV;
+
+/// `C_VerifyFinal` finishes a multiple-part verification operation, checking the signature.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pSignature`: signature to verify
+/// * `ulSignatureLen`: signature length
+///
+pub type C_VerifyFinal = extern "C" fn(hSession: CK_SESSION_HANDLE, pSignature: CK_BYTE_PTR, ulSignatureLen: CK_ULONG) -> CK_RV;
+
+/// `C_VerifyRecoverInit` initializes a signature verification operation, where the data is recovered from the signature.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pMechanism`: the verification mechanism
+/// * `hKey`: verification key
+///
+pub type C_VerifyRecoverInit = extern "C" fn(hSession: CK_SESSION_HANDLE, pMechanism: CK_MECHANISM_PTR, hKey: CK_OBJECT_HANDLE) -> CK_RV;
+
+/// `C_VerifyRecover` verifies a signature in a single-part operation, where the data is recovered from the signature.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pSignature`: signature to verify
+/// * `ulSignatureLen`: signature length
+/// * `pData`: gets signed data
+/// * `pulDataLen`: gets signed data len
+///
+pub type C_VerifyRecover = extern "C" fn(hSession: CK_SESSION_HANDLE, pSignature: CK_BYTE_PTR, ulSignatureLen: CK_ULONG, pData: CK_BYTE_PTR, pulDataLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_DigestEncryptUpdate` continues a multiple-part digesting and encryption operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `pPart`: the plaintext data
+/// * `ulPartLen`: plaintext length
+/// * `pEncryptedPart`: gets ciphertext
+/// * `pulEncryptedPartLen`: gets c-text length
+///
+pub type C_DigestEncryptUpdate = extern "C" fn(hSession: CK_SESSION_HANDLE, pPart: CK_BYTE_PTR, ulPartLen: CK_ULONG, pEncryptedPart: CK_BYTE_PTR, pulEncryptedPartLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_DecryptDigestUpdate` continues a multiple-part decryption and digesting operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `pEncryptedPart`: ciphertext
+/// * `ulEncryptedPartLen`: ciphertext length
+/// * `pPart:`: gets plaintext
+/// * `pulPartLen`: gets plaintext len
+///
+pub type C_DecryptDigestUpdate = extern "C" fn(hSession: CK_SESSION_HANDLE, pEncryptedPart: CK_BYTE_PTR, ulEncryptedPartLen: CK_ULONG, pPart: CK_BYTE_PTR, pulPartLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_SignEncryptUpdate` continues a multiple-part signing and encryption operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `pPart`: the plaintext data
+/// * `ulPartLen`: plaintext length
+/// * `pEncryptedPart`: gets ciphertext
+/// * `pulEncryptedPartLen`: gets c-text length
+///
+pub type C_SignEncryptUpdate = extern "C" fn(hSession: CK_SESSION_HANDLE, pPart: CK_BYTE_PTR, ulPartLen: CK_ULONG, pEncryptedPart: CK_BYTE_PTR, pulEncryptedPartLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_DecryptVerifyUpdate` continues a multiple-part decryption and verify operation.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `pEncryptedPart`: ciphertext
+/// * `ulEncryptedPartLen`: ciphertext length
+/// * `pPart`: gets plaintext
+/// * `pulPartLen`: gets p-text length
+///
+pub type C_DecryptVerifyUpdate = extern "C" fn(hSession: CK_SESSION_HANDLE, pEncryptedPart: CK_BYTE_PTR, ulEncryptedPartLen: CK_ULONG, pPart: CK_BYTE_PTR, pulPartLen: CK_ULONG_PTR) -> CK_RV;
+
+/// `C_GenerateKey` generates a secret key, creating a new key object.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pMechanism`: key generation mech.
+/// * `pTemplate`: template for new key
+/// * `ulCount`: # of attrs in template
+/// * `phKey`: gets handle of new key
+///
+pub type C_GenerateKey = extern "C" fn(hSession: CK_SESSION_HANDLE, pMechanism: CK_MECHANISM_PTR, pTemplate: CK_ATTRIBUTE_PTR, ulCount: CK_ULONG, phKey: CK_OBJECT_HANDLE_PTR) -> CK_RV;
+
+/// `C_GenerateKeyPair` generates a public-key/private-key pair, creating new key objects.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session handle
+/// * `pMechanism`: key-gen mech.
+/// * `pPublicKeyTemplate`: template for pub. key
+/// * `ulPublicKeyAttributeCount`: # pub. attrs.
+/// * `pPrivateKeyTemplate`: template for priv. key
+/// * `ulPrivateKeyAttributeCount`: # priv. attrs.
+/// * `phPublicKey`: gets pub. key handle
+/// * `phPrivateKey`: gets priv. key handle
+///
+pub type C_GenerateKeyPair = extern "C" fn(
+ hSession: CK_SESSION_HANDLE,
+ pMechanism: CK_MECHANISM_PTR,
+ pPublicKeyTemplate: CK_ATTRIBUTE_PTR,
+ ulPublicKeyAttributeCount: CK_ULONG,
+ pPrivateKeyTemplate: CK_ATTRIBUTE_PTR,
+ ulPrivateKeyAttributeCount: CK_ULONG,
+ phPublicKey: CK_OBJECT_HANDLE_PTR,
+ phPrivateKey: CK_OBJECT_HANDLE_PTR,
+) -> CK_RV;
+
+/// `C_WrapKey` wraps (i.e., encrypts) a key.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pMechanism`: the wrapping mechanism
+/// * `hWrappingKey`: wrapping key
+/// * `hKey`: key to be wrapped
+/// * `pWrappedKey`: gets wrapped key
+/// * `pulWrappedKeyLen`: gets wrapped key size
+///
+pub type C_WrapKey = extern "C" fn(
+ hSession: CK_SESSION_HANDLE,
+ pMechanism: CK_MECHANISM_PTR,
+ hWrappingKey: CK_OBJECT_HANDLE,
+ hKey: CK_OBJECT_HANDLE,
+ pWrappedKey: CK_BYTE_PTR,
+ pulWrappedKeyLen: CK_ULONG_PTR,
+) -> CK_RV;
+
+/// `C_UnwrapKey` unwraps (decrypts) a wrapped key, creating a new key object.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `pMechanism`: unwrapping mech.
+/// * `hUnwrappingKey`: unwrapping key
+/// * `pWrappedKey`: the wrapped key
+/// * `ulWrappedKeyLen`: wrapped key len
+/// * `pTemplate`: new key template
+/// * `ulAttributeCount`: template length
+/// * `phKey`: gets new handle
+///
+pub type C_UnwrapKey = extern "C" fn(
+ hSession: CK_SESSION_HANDLE,
+ pMechanism: CK_MECHANISM_PTR,
+ hUnwrappingKey: CK_OBJECT_HANDLE,
+ pWrappedKey: CK_BYTE_PTR,
+ ulWrappedKeyLen: CK_ULONG,
+ pTemplate: CK_ATTRIBUTE_PTR,
+ ulAttributeCount: CK_ULONG,
+ phKey: CK_OBJECT_HANDLE_PTR,
+) -> CK_RV;
+
+/// `C_DeriveKey` derives a key from a base key, creating a new key object.
+///
+/// # Function Parameters
+///
+/// * `hSession`: session's handle
+/// * `pMechanism`: key deriv. mech.
+/// * `hBaseKey`: base key
+/// * `pTemplate`: new key template
+/// * `ulAttributeCount`: template length
+/// * `phKey`: gets new handle
+///
+pub type C_DeriveKey = extern "C" fn(
+ hSession: CK_SESSION_HANDLE,
+ pMechanism: CK_MECHANISM_PTR,
+ hBaseKey: CK_OBJECT_HANDLE,
+ pTemplate: CK_ATTRIBUTE_PTR,
+ ulAttributeCount: CK_ULONG,
+ phKey: CK_OBJECT_HANDLE_PTR,
+) -> CK_RV;
+
+/// `C_SeedRandom` mixes additional seed material into the token's random number generator.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `pSeed`: the seed material
+/// * `ulSeedLen`: length of seed material
+///
+pub type C_SeedRandom = extern "C" fn(hSession: CK_SESSION_HANDLE, pSeed: CK_BYTE_PTR, ulSeedLen: CK_ULONG) -> CK_RV;
+
+/// `C_GenerateRandom` generates random data.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+/// * `RandomData`: receives the random data
+/// * `ulRandomLen`: # of bytes to generate
+///
+pub type C_GenerateRandom = extern "C" fn(hSession: CK_SESSION_HANDLE, RandomData: CK_BYTE_PTR, ulRandomLen: CK_ULONG) -> CK_RV;
+
+/// `C_GetFunctionStatus` is a legacy function; it obtains an updated status of a function running in parallel with an application.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+///
+pub type C_GetFunctionStatus = extern "C" fn(hSession: CK_SESSION_HANDLE) -> CK_RV;
+
+/// `C_CancelFunction` is a legacy function; it cancels a function running in parallel.
+///
+/// # Function Parameters
+///
+/// * `hSession`: the session's handle
+///
+pub type C_CancelFunction = extern "C" fn(hSession: CK_SESSION_HANDLE) -> CK_RV;
+
+/// `C_WaitForSlotEvent` waits for a slot event (token insertion, removal, etc.) to occur.
+///
+/// # Function Parameters
+///
+/// * `flags`: blocking/nonblocking flag
+/// * `pSlot`: location that receives the slot ID
+/// * `pRserved`: reserved. Should be NULL_PTR
+///
+pub type C_WaitForSlotEvent = extern "C" fn(flags: CK_FLAGS, pSlot: CK_SLOT_ID_PTR, pRserved: CK_VOID_PTR) -> CK_RV;
diff --git a/third_party/rust/pkcs11/src/lib.rs b/third_party/rust/pkcs11/src/lib.rs
new file mode 100644
index 0000000000..1c71ff0385
--- /dev/null
+++ b/third_party/rust/pkcs11/src/lib.rs
@@ -0,0 +1,1298 @@
+// Copyright 2017 Marcus Heese
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#![allow(non_camel_case_types, non_snake_case)]
+
+extern crate libloading;
+extern crate num_bigint;
+
+#[cfg(test)]
+#[macro_use] extern crate serial_test_derive;
+
+#[cfg(test)]
+mod tests;
+
+/// This module is basically a full conversion of the `pkcs11t.h` C header file.
+pub mod types;
+/// This module is basically a full conversion of the `pkcs11f.h` C header file.
+pub mod functions;
+/// The error types are defined here - they are used throughout the crate.
+pub mod errors;
+
+use types::*;
+use functions::*;
+use errors::Error;
+
+
+use std::mem;
+use std::path::Path;
+use std::ptr;
+use std::ffi::CString;
+//use libc::c_uchar;
+
+
+trait CkFrom<T> {
+ fn from(T) -> Self;
+}
+
+impl CkFrom<bool> for CK_BBOOL {
+ fn from(b: bool) -> Self {
+ match b {
+ true => 1,
+ false => 0,
+ }
+ }
+}
+
+impl CkFrom<CK_BBOOL> for bool {
+ fn from(b: CK_BBOOL) -> bool {
+ match b {
+ 0 => false,
+ _ => true,
+ }
+ }
+}
+
+fn label_from_str(label: &str) -> [CK_UTF8CHAR; 32] {
+ // initialize a fixed-size array with whitespace characters
+ let mut lab: [CK_UTF8CHAR; 32] = [32; 32];
+ let mut i = 0;
+ for c in label.chars() {
+ if i + c.len_utf8() <= 32 {
+ let mut buf = [0; 4];
+ let bytes = c.encode_utf8(&mut buf).as_bytes();
+ for b in bytes {
+ lab[i] = b.clone();
+ i += 1;
+ }
+ } else {
+ break;
+ }
+ }
+ lab
+}
+
+#[derive(Debug)]
+pub struct Ctx {
+ lib: libloading::Library,
+ _is_initialized: bool,
+ version: CK_VERSION,
+ C_Initialize: C_Initialize,
+ C_Finalize: C_Finalize,
+ C_GetInfo: C_GetInfo,
+ C_GetFunctionList: C_GetFunctionList,
+ C_GetSlotList: C_GetSlotList,
+ C_GetSlotInfo: C_GetSlotInfo,
+ C_GetTokenInfo: C_GetTokenInfo,
+ C_GetMechanismList: C_GetMechanismList,
+ C_GetMechanismInfo: C_GetMechanismInfo,
+ C_InitToken: C_InitToken,
+ C_InitPIN: C_InitPIN,
+ C_SetPIN: C_SetPIN,
+ C_OpenSession: C_OpenSession,
+ C_CloseSession: C_CloseSession,
+ C_CloseAllSessions: C_CloseAllSessions,
+ C_GetSessionInfo: C_GetSessionInfo,
+ C_GetOperationState: C_GetOperationState,
+ C_SetOperationState: C_SetOperationState,
+ C_Login: C_Login,
+ C_Logout: C_Logout,
+ C_CreateObject: C_CreateObject,
+ C_CopyObject: C_CopyObject,
+ C_DestroyObject: C_DestroyObject,
+ C_GetObjectSize: C_GetObjectSize,
+ C_GetAttributeValue: C_GetAttributeValue,
+ C_SetAttributeValue: C_SetAttributeValue,
+ C_FindObjectsInit: C_FindObjectsInit,
+ C_FindObjects: C_FindObjects,
+ C_FindObjectsFinal: C_FindObjectsFinal,
+ C_EncryptInit: C_EncryptInit,
+ C_Encrypt: C_Encrypt,
+ C_EncryptUpdate: C_EncryptUpdate,
+ C_EncryptFinal: C_EncryptFinal,
+ C_DecryptInit: C_DecryptInit,
+ C_Decrypt: C_Decrypt,
+ C_DecryptUpdate: C_DecryptUpdate,
+ C_DecryptFinal: C_DecryptFinal,
+ C_DigestInit: C_DigestInit,
+ C_Digest: C_Digest,
+ C_DigestUpdate: C_DigestUpdate,
+ C_DigestKey: C_DigestKey,
+ C_DigestFinal: C_DigestFinal,
+ C_SignInit: C_SignInit,
+ C_Sign: C_Sign,
+ C_SignUpdate: C_SignUpdate,
+ C_SignFinal: C_SignFinal,
+ C_SignRecoverInit: C_SignRecoverInit,
+ C_SignRecover: C_SignRecover,
+ C_VerifyInit: C_VerifyInit,
+ C_Verify: C_Verify,
+ C_VerifyUpdate: C_VerifyUpdate,
+ C_VerifyFinal: C_VerifyFinal,
+ C_VerifyRecoverInit: C_VerifyRecoverInit,
+ C_VerifyRecover: C_VerifyRecover,
+ C_DigestEncryptUpdate: C_DigestEncryptUpdate,
+ C_DecryptDigestUpdate: C_DecryptDigestUpdate,
+ C_SignEncryptUpdate: C_SignEncryptUpdate,
+ C_DecryptVerifyUpdate: C_DecryptVerifyUpdate,
+ C_GenerateKey: C_GenerateKey,
+ C_GenerateKeyPair: C_GenerateKeyPair,
+ C_WrapKey: C_WrapKey,
+ C_UnwrapKey: C_UnwrapKey,
+ C_DeriveKey: C_DeriveKey,
+ C_SeedRandom: C_SeedRandom,
+ C_GenerateRandom: C_GenerateRandom,
+ C_GetFunctionStatus: C_GetFunctionStatus,
+ C_CancelFunction: C_CancelFunction,
+ // Functions added in for Cryptoki Version 2.01 or later
+ C_WaitForSlotEvent: Option<C_WaitForSlotEvent>,
+}
+
+impl Ctx {
+ pub fn new<P>(filename: P) -> Result<Ctx, Error>
+ where
+ P: AsRef<Path>,
+ {
+ unsafe {
+ let lib = libloading::Library::new(filename.as_ref())?;
+ let mut list: CK_FUNCTION_LIST_PTR = mem::uninitialized();
+ {
+ let func: libloading::Symbol<unsafe extern "C" fn(CK_FUNCTION_LIST_PTR_PTR) -> CK_RV> = lib.get(b"C_GetFunctionList")?;
+ match func(&mut list) {
+ CKR_OK => (),
+ err => return Err(Error::Pkcs11(err)),
+ }
+ }
+
+ Ok(Ctx {
+ lib: lib,
+ _is_initialized: false,
+ version: (*list).version.clone(),
+ C_Initialize: (*list).C_Initialize.ok_or(Error::Module("C_Initialize function not found"))?,
+ C_Finalize: (*list).C_Finalize.ok_or(Error::Module("C_Finalize function not found"))?,
+ C_GetInfo: (*list).C_GetInfo.ok_or(Error::Module("C_GetInfo function not found"))?,
+ C_GetFunctionList: (*list).C_GetFunctionList.ok_or(Error::Module("C_GetFunctionList function not found"))?,
+ C_GetSlotList: (*list).C_GetSlotList.ok_or(Error::Module("C_GetSlotList function not found"))?,
+ C_GetSlotInfo: (*list).C_GetSlotInfo.ok_or(Error::Module("C_GetSlotInfo function not found"))?,
+ C_GetTokenInfo: (*list).C_GetTokenInfo.ok_or(Error::Module("C_GetTokenInfo function not found"))?,
+ C_GetMechanismList: (*list).C_GetMechanismList.ok_or(Error::Module("C_GetMechanismList function not found"))?,
+ C_GetMechanismInfo: (*list).C_GetMechanismInfo.ok_or(Error::Module("C_GetMechanismInfo function not found"))?,
+ C_InitToken: (*list).C_InitToken.ok_or(Error::Module("C_InitToken function not found"))?,
+ C_InitPIN: (*list).C_InitPIN.ok_or(Error::Module("C_InitPIN function not found"))?,
+ C_SetPIN: (*list).C_SetPIN.ok_or(Error::Module("C_SetPIN function not found"))?,
+ C_OpenSession: (*list).C_OpenSession.ok_or(Error::Module("C_OpenSession function not found"))?,
+ C_CloseSession: (*list).C_CloseSession.ok_or(Error::Module("C_CloseSession function not found"))?,
+ C_CloseAllSessions: (*list).C_CloseAllSessions.ok_or(Error::Module("C_CloseAllSessions function not found"))?,
+ C_GetSessionInfo: (*list).C_GetSessionInfo.ok_or(Error::Module("C_GetSessionInfo function not found"))?,
+ C_GetOperationState: (*list).C_GetOperationState.ok_or(Error::Module("C_GetOperationState function not found"))?,
+ C_SetOperationState: (*list).C_SetOperationState.ok_or(Error::Module("C_SetOperationState function not found"))?,
+ C_Login: (*list).C_Login.ok_or(Error::Module("C_Login function not found"))?,
+ C_Logout: (*list).C_Logout.ok_or(Error::Module("C_Logout function not found"))?,
+ C_CreateObject: (*list).C_CreateObject.ok_or(Error::Module("C_CreateObject function not found"))?,
+ C_CopyObject: (*list).C_CopyObject.ok_or(Error::Module("C_CopyObject function not found"))?,
+ C_DestroyObject: (*list).C_DestroyObject.ok_or(Error::Module("C_DestroyObject function not found"))?,
+ C_GetObjectSize: (*list).C_GetObjectSize.ok_or(Error::Module("C_GetObjectSize function not found"))?,
+ C_GetAttributeValue: (*list).C_GetAttributeValue.ok_or(Error::Module("C_GetAttributeValue function not found"))?,
+ C_SetAttributeValue: (*list).C_SetAttributeValue.ok_or(Error::Module("C_SetAttributeValue function not found"))?,
+ C_FindObjectsInit: (*list).C_FindObjectsInit.ok_or(Error::Module("C_FindObjectsInit function not found"))?,
+ C_FindObjects: (*list).C_FindObjects.ok_or(Error::Module("C_FindObjects function not found"))?,
+ C_FindObjectsFinal: (*list).C_FindObjectsFinal.ok_or(Error::Module("C_FindObjectsFinal function not found"))?,
+ C_EncryptInit: (*list).C_EncryptInit.ok_or(Error::Module("C_EncryptInit function not found"))?,
+ C_Encrypt: (*list).C_Encrypt.ok_or(Error::Module("C_Encrypt function not found"))?,
+ C_EncryptUpdate: (*list).C_EncryptUpdate.ok_or(Error::Module("C_EncryptUpdate function not found"))?,
+ C_EncryptFinal: (*list).C_EncryptFinal.ok_or(Error::Module("C_EncryptFinal function not found"))?,
+ C_DecryptInit: (*list).C_DecryptInit.ok_or(Error::Module("C_DecryptInit function not found"))?,
+ C_Decrypt: (*list).C_Decrypt.ok_or(Error::Module("C_Decrypt function not found"))?,
+ C_DecryptUpdate: (*list).C_DecryptUpdate.ok_or(Error::Module("C_DecryptUpdate function not found"))?,
+ C_DecryptFinal: (*list).C_DecryptFinal.ok_or(Error::Module("C_DecryptFinal function not found"))?,
+ C_DigestInit: (*list).C_DigestInit.ok_or(Error::Module("C_DigestInit function not found"))?,
+ C_Digest: (*list).C_Digest.ok_or(Error::Module("C_Digest function not found"))?,
+ C_DigestUpdate: (*list).C_DigestUpdate.ok_or(Error::Module("C_DigestUpdate function not found"))?,
+ C_DigestKey: (*list).C_DigestKey.ok_or(Error::Module("C_DigestKey function not found"))?,
+ C_DigestFinal: (*list).C_DigestFinal.ok_or(Error::Module("C_DigestFinal function not found"))?,
+ C_SignInit: (*list).C_SignInit.ok_or(Error::Module("C_SignInit function not found"))?,
+ C_Sign: (*list).C_Sign.ok_or(Error::Module("C_Sign function not found"))?,
+ C_SignUpdate: (*list).C_SignUpdate.ok_or(Error::Module("C_SignUpdate function not found"))?,
+ C_SignFinal: (*list).C_SignFinal.ok_or(Error::Module("C_SignFinal function not found"))?,
+ C_SignRecoverInit: (*list).C_SignRecoverInit.ok_or(Error::Module("C_SignRecoverInit function not found"))?,
+ C_SignRecover: (*list).C_SignRecover.ok_or(Error::Module("C_SignRecover function not found"))?,
+ C_VerifyInit: (*list).C_VerifyInit.ok_or(Error::Module("C_VerifyInit function not found"))?,
+ C_Verify: (*list).C_Verify.ok_or(Error::Module("C_Verify function not found"))?,
+ C_VerifyUpdate: (*list).C_VerifyUpdate.ok_or(Error::Module("C_VerifyUpdate function not found"))?,
+ C_VerifyFinal: (*list).C_VerifyFinal.ok_or(Error::Module("C_VerifyFinal function not found"))?,
+ C_VerifyRecoverInit: (*list).C_VerifyRecoverInit.ok_or(Error::Module("C_VerifyRecoverInit function not found"))?,
+ C_VerifyRecover: (*list).C_VerifyRecover.ok_or(Error::Module("C_VerifyRecover function not found"))?,
+ C_DigestEncryptUpdate: (*list).C_DigestEncryptUpdate.ok_or(Error::Module("C_DigestEncryptUpdate function not found"))?,
+ C_DecryptDigestUpdate: (*list).C_DecryptDigestUpdate.ok_or(Error::Module("C_DecryptDigestUpdate function not found"))?,
+ C_SignEncryptUpdate: (*list).C_SignEncryptUpdate.ok_or(Error::Module("C_SignEncryptUpdate function not found"))?,
+ C_DecryptVerifyUpdate: (*list).C_DecryptVerifyUpdate.ok_or(Error::Module("C_DecryptVerifyUpdate function not found"))?,
+ C_GenerateKey: (*list).C_GenerateKey.ok_or(Error::Module("C_GenerateKey function not found"))?,
+ C_GenerateKeyPair: (*list).C_GenerateKeyPair.ok_or(Error::Module("C_GenerateKeyPair function not found"))?,
+ C_WrapKey: (*list).C_WrapKey.ok_or(Error::Module("C_WrapKey function not found"))?,
+ C_UnwrapKey: (*list).C_UnwrapKey.ok_or(Error::Module("C_UnwrapKey function not found"))?,
+ C_DeriveKey: (*list).C_DeriveKey.ok_or(Error::Module("C_DeriveKey function not found"))?,
+ C_SeedRandom: (*list).C_SeedRandom.ok_or(Error::Module("C_SeedRandom function not found"))?,
+ C_GenerateRandom: (*list).C_GenerateRandom.ok_or(Error::Module("C_GenerateRandom function not found"))?,
+ C_GetFunctionStatus: (*list).C_GetFunctionStatus.ok_or(Error::Module("C_GetFunctionStatus function not found"))?,
+ C_CancelFunction: (*list).C_CancelFunction.ok_or(Error::Module("C_CancelFunction function not found"))?,
+ // Functions added in for Cryptoki Version 2.01 or later
+ C_WaitForSlotEvent: (*list).C_WaitForSlotEvent,
+ })
+ }
+ }
+
+ pub fn new_and_initialize<P>(filename: P) -> Result<Ctx, Error>
+ where
+ P: AsRef<Path>,
+ {
+ let mut ctx = Ctx::new(filename)?;
+ ctx.initialize(None)?;
+ Ok(ctx)
+ }
+
+ pub fn is_initialized(&self) -> bool {
+ self._is_initialized
+ }
+
+ fn initialized(&self) -> Result<(), Error> {
+ if !self._is_initialized {
+ Err(Error::Module("module not initialized"))
+ } else {
+ Ok(())
+ }
+ }
+
+ fn not_initialized(&self) -> Result<(), Error> {
+ if self._is_initialized {
+ Err(Error::Module("module already initialized"))
+ } else {
+ Ok(())
+ }
+ }
+
+ pub fn initialize(&mut self, init_args: Option<CK_C_INITIALIZE_ARGS>) -> Result<(), Error> {
+ self.not_initialized()?;
+ // if no args are specified, library expects NULL
+ let init_args = match init_args {
+ Some(mut args) => &mut args,
+ None => ptr::null_mut()
+ };
+ match (self.C_Initialize)(init_args) {
+ CKR_OK => {
+ self._is_initialized = true;
+ Ok(())
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn finalize(&mut self) -> Result<(), Error> {
+ self.initialized()?;
+ match (self.C_Finalize)(ptr::null_mut()) {
+ CKR_OK => {
+ self._is_initialized = false;
+ Ok(())
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_info(&self) -> Result<CK_INFO, Error> {
+ self.initialized()?;
+ let mut info = CK_INFO::new();
+ match (self.C_GetInfo)(&mut info) {
+ CKR_OK => Ok(info),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_function_list(&self) -> Result<CK_FUNCTION_LIST, Error> {
+ let mut list: CK_FUNCTION_LIST_PTR = unsafe { mem::uninitialized() };
+ match (self.C_GetFunctionList)(&mut list) {
+ CKR_OK => unsafe { Ok((*list).clone()) },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_slot_list(&self, token_present: bool) -> Result<Vec<CK_SLOT_ID>, Error> {
+ self.initialized()?;
+ let mut slots_len: CK_ULONG = 0;
+ match (self.C_GetSlotList)(CkFrom::from(token_present), ptr::null_mut(), &mut slots_len) {
+ CKR_OK => {
+ // now slots_len contains the number of slots,
+ // and we can generate a vector with the right capacity
+ // important is to pass slots_len **again** because in
+ // the 2nd call it is used to tell C how big the memory
+ // in slots is.
+ let mut slots = Vec::<CK_SLOT_ID>::with_capacity(slots_len as usize);
+ let slots_ptr = slots.as_mut_ptr();
+ match (self.C_GetSlotList)(CkFrom::from(token_present), slots_ptr, &mut slots_len) {
+ CKR_OK => {
+ unsafe {
+ slots.set_len(slots_len as usize);
+ }
+ Ok(slots)
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_slot_info(&self, slot_id: CK_SLOT_ID) -> Result<CK_SLOT_INFO, Error> {
+ self.initialized()?;
+ let mut info: CK_SLOT_INFO = Default::default();
+ match (self.C_GetSlotInfo)(slot_id, &mut info) {
+ CKR_OK => Ok(info),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_token_info(&self, slot_id: CK_SLOT_ID) -> Result<CK_TOKEN_INFO, Error> {
+ self.initialized()?;
+ let mut info: CK_TOKEN_INFO = Default::default();
+ match (self.C_GetTokenInfo)(slot_id, &mut info) {
+ CKR_OK => Ok(info),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_mechanism_list(&self, slot_id: CK_SLOT_ID) -> Result<Vec<CK_MECHANISM_TYPE>, Error> {
+ self.initialized()?;
+ let mut count: CK_ULONG = 0;
+ match (self.C_GetMechanismList)(slot_id, ptr::null_mut(), &mut count) {
+ CKR_OK => {
+ // see get_slot_list() for an explanation - it works the same way
+ let mut list = Vec::<CK_MECHANISM_TYPE>::with_capacity(count as usize);
+ let list_ptr = list.as_mut_ptr();
+ match (self.C_GetMechanismList)(slot_id, list_ptr, &mut count) {
+ CKR_OK => {
+ unsafe {
+ list.set_len(count as usize);
+ }
+ Ok(list)
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_mechanism_info(&self, slot_id: CK_SLOT_ID, mechanism_type: CK_MECHANISM_TYPE) -> Result<CK_MECHANISM_INFO, Error> {
+ self.initialized()?;
+ let mut info: CK_MECHANISM_INFO = Default::default();
+ match (self.C_GetMechanismInfo)(slot_id, mechanism_type, &mut info) {
+ CKR_OK => Ok(info),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn init_token<'a, 'b>(&self, slot_id: CK_SLOT_ID, pin: Option<&'a str>, label: &'b str) -> Result<(), Error> {
+ self.initialized()?;
+ let mut formatted_label = label_from_str(label).to_vec();
+ let formatted_label_ptr = formatted_label.as_mut_ptr();
+ match pin {
+ Some(pin) => if let Ok(cpin) = CString::new(pin) {
+ let mut cpin_bytes = cpin.into_bytes();
+ match (self.C_InitToken)(slot_id, cpin_bytes.as_mut_ptr(), cpin_bytes.len() as CK_ULONG, formatted_label_ptr) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ } else {
+ Err(Error::InvalidInput("PIN contains a nul byte"))
+ },
+ None => {
+ // CKF_PROTECTED_AUTHENTICATION_PATH requires a NULL pointer
+ match (self.C_InitToken)(slot_id, ptr::null_mut(), 0, formatted_label_ptr) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+ }
+ }
+
+ pub fn init_pin<'a>(&self, session: CK_SESSION_HANDLE, pin: Option<&'a str>) -> Result<(), Error> {
+ self.initialized()?;
+ match pin {
+ Some(pin) => if let Ok(cpin) = CString::new(pin) {
+ let mut cpin_bytes = cpin.into_bytes();
+ match (self.C_InitPIN)(session, cpin_bytes.as_mut_ptr(), cpin_bytes.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ } else {
+ Err(Error::InvalidInput("PIN contains a nul byte"))
+ },
+ None => match (self.C_InitPIN)(session, ptr::null_mut(), 0) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ },
+ }
+ }
+
+ pub fn set_pin<'a, 'b>(&self, session: CK_SESSION_HANDLE, old_pin: Option<&'a str>, new_pin: Option<&'b str>) -> Result<(), Error> {
+ self.initialized()?;
+ if old_pin.is_none() && new_pin.is_none() {
+ match (self.C_SetPIN)(session, ptr::null_mut(), 0, ptr::null_mut(), 0) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ } else if old_pin.is_some() && new_pin.is_some() {
+ let old_cpin_res = CString::new(old_pin.unwrap());
+ let new_cpin_res = CString::new(new_pin.unwrap());
+ if old_cpin_res.is_err() {
+ return Err(Error::InvalidInput("Old PIN contains a nul byte"));
+ }
+ if new_cpin_res.is_err() {
+ return Err(Error::InvalidInput("New PIN contains a nul byte"));
+ }
+ let mut old_cpin = old_cpin_res.unwrap().into_bytes();
+ let mut new_cpin = new_cpin_res.unwrap().into_bytes();
+ match (self.C_SetPIN)(session, old_cpin.as_mut_ptr(), old_cpin.len() as CK_ULONG, new_cpin.as_mut_ptr(), new_cpin.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ } else {
+ Err(Error::InvalidInput("both PINs must be either set or unset"))
+ }
+ }
+
+ pub fn open_session(&self, slot_id: CK_SLOT_ID, flags: CK_FLAGS, application: Option<CK_VOID_PTR>, notify: CK_NOTIFY) -> Result<CK_SESSION_HANDLE, Error> {
+ self.initialized()?;
+ let mut session: CK_SESSION_HANDLE = 0;
+ match (self.C_OpenSession)(slot_id, flags, application.unwrap_or(ptr::null_mut()), notify, &mut session) {
+ CKR_OK => Ok(session),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn close_session(&self, session: CK_SESSION_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ match (self.C_CloseSession)(session) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn close_all_sessions(&self, slot_id: CK_SLOT_ID) -> Result<(), Error> {
+ self.initialized()?;
+ match (self.C_CloseAllSessions)(slot_id) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_session_info(&self, session: CK_SESSION_HANDLE) -> Result<CK_SESSION_INFO, Error> {
+ self.initialized()?;
+ let mut info: CK_SESSION_INFO = Default::default();
+ match (self.C_GetSessionInfo)(session, &mut info) {
+ CKR_OK => Ok(info),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_operation_state(&self, session: CK_SESSION_HANDLE) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut state_length: CK_ULONG = 0;
+ match (self.C_GetOperationState)(session, ptr::null_mut(), &mut state_length) {
+ CKR_OK => {
+ let mut state: Vec<CK_BYTE> = Vec::with_capacity(state_length as usize);
+ let state_ptr = state.as_mut_ptr();
+ match (self.C_GetOperationState)(session, state_ptr, &mut state_length) {
+ CKR_OK => {
+ unsafe {
+ state.set_len(state_length as usize);
+ }
+ Ok(state)
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn set_operation_state(
+ &self,
+ session: CK_SESSION_HANDLE,
+ operation_state: Vec<CK_BYTE>,
+ encryption_key: Option<CK_OBJECT_HANDLE>,
+ authentication_key: Option<CK_OBJECT_HANDLE>,
+ ) -> Result<(), Error> {
+ self.initialized()?;
+ let mut operation_state = operation_state.clone();
+ match (self.C_SetOperationState)(session, operation_state.as_mut_ptr(), operation_state.len() as CK_ULONG, encryption_key.unwrap_or(0), authentication_key.unwrap_or(0)) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn login<'a>(&self, session: CK_SESSION_HANDLE, user_type: CK_USER_TYPE, pin: Option<&'a str>) -> Result<(), Error> {
+ self.initialized()?;
+ match pin {
+ Some(pin) => if let Ok(cpin) = CString::new(pin) {
+ let mut cpin_bytes = cpin.into_bytes();
+ match (self.C_Login)(session, user_type, cpin_bytes.as_mut_ptr(), cpin_bytes.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ } else {
+ Err(Error::InvalidInput("PIN contains a nul byte"))
+ },
+ None => match (self.C_Login)(session, user_type, ptr::null_mut(), 0) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ },
+ }
+ }
+
+ // Some dongle drivers (such as Safenet) allow NUL bytes in PINs, and fail
+ // login if a NUL containing PIN is truncated. Combined with poor PIN gen
+ // algorithms which insert NULs into the PIN, you might need a way to supply
+ // raw bytes for a PIN, instead of converting from a UTF8 string as per spec
+ pub fn login_with_raw<'a>(&self, session: CK_SESSION_HANDLE, user_type: CK_USER_TYPE, pin: Option<&Vec<CK_BYTE>>) -> Result<(), Error> {
+ self.initialized()?;
+ match pin {
+ Some(pin) => {
+ let mut pin = pin.clone();
+ match (self.C_Login)(session, user_type, pin.as_mut_ptr(), pin.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ None => match (self.C_Login)(session, user_type, ptr::null_mut(), 0) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ },
+ }
+ }
+
+ pub fn logout(&self, session: CK_SESSION_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ match (self.C_Logout)(session) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn create_object(&self, session: CK_SESSION_HANDLE, template: &Vec<CK_ATTRIBUTE>) -> Result<CK_OBJECT_HANDLE, Error> {
+ self.initialized()?;
+ let mut template = template.clone();
+ let mut oh: CK_OBJECT_HANDLE = CK_INVALID_HANDLE;
+ match (self.C_CreateObject)(session, template.as_mut_ptr(), template.len() as CK_ULONG, &mut oh) {
+ CKR_OK => Ok(oh),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn copy_object(&self, session: CK_SESSION_HANDLE, object: CK_OBJECT_HANDLE, template: &Vec<CK_ATTRIBUTE>) -> Result<CK_OBJECT_HANDLE, Error> {
+ self.initialized()?;
+ let mut template = template.clone();
+ let mut oh: CK_OBJECT_HANDLE = CK_INVALID_HANDLE;
+ match (self.C_CopyObject)(session, object, template.as_mut_ptr(), template.len() as CK_ULONG, &mut oh) {
+ CKR_OK => Ok(oh),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn destroy_object(&self, session: CK_SESSION_HANDLE, object: CK_OBJECT_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ match (self.C_DestroyObject)(session, object) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_object_size(&self, session: CK_SESSION_HANDLE, object: CK_OBJECT_HANDLE) -> Result<CK_ULONG, Error> {
+ self.initialized()?;
+ let mut size: CK_ULONG = 0;
+ match (self.C_GetObjectSize)(session, object, &mut size) {
+ CKR_OK => Ok(size),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_attribute_value<'a>(&self, session: CK_SESSION_HANDLE, object: CK_OBJECT_HANDLE, template: &'a mut Vec<CK_ATTRIBUTE>) -> Result<(CK_RV, &'a Vec<CK_ATTRIBUTE>), Error> {
+ self.initialized()?;
+ /*
+ Note that the error codes CKR_ATTRIBUTE_SENSITIVE, CKR_ATTRIBUTE_TYPE_INVALID, and CKR_BUFFER_TOO_SMALL
+ do not denote true errors for C_GetAttributeValue. If a call to C_GetAttributeValue returns any of these three
+ values, then the call MUST nonetheless have processed every attribute in the template supplied to
+ C_GetAttributeValue. Each attribute in the template whose value can be returned by the call to
+ C_GetAttributeValue will be returned by the call to C_GetAttributeValue.
+ */
+ match (self.C_GetAttributeValue)(session, object, template.as_mut_ptr(), template.len() as CK_ULONG) {
+ CKR_OK => Ok((CKR_OK, template)),
+ CKR_ATTRIBUTE_SENSITIVE => Ok((CKR_ATTRIBUTE_SENSITIVE, template)),
+ CKR_ATTRIBUTE_TYPE_INVALID => Ok((CKR_ATTRIBUTE_TYPE_INVALID, template)),
+ CKR_BUFFER_TOO_SMALL => Ok((CKR_BUFFER_TOO_SMALL, template)),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn set_attribute_value(&self, session: CK_SESSION_HANDLE, object: CK_OBJECT_HANDLE, template: &Vec<CK_ATTRIBUTE>) -> Result<(), Error> {
+ self.initialized()?;
+ let mut template = template.clone();
+ match (self.C_SetAttributeValue)(session, object, template.as_mut_ptr(), template.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn find_objects_init(&self, session: CK_SESSION_HANDLE, template: &Vec<CK_ATTRIBUTE>) -> Result<(), Error> {
+ self.initialized()?;
+ let mut template = template.clone();
+ match (self.C_FindObjectsInit)(session, template.as_mut_ptr(), template.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn find_objects(&self, session: CK_SESSION_HANDLE, max_object_count: CK_ULONG) -> Result<Vec<CK_OBJECT_HANDLE>, Error> {
+ self.initialized()?;
+ let mut list: Vec<CK_OBJECT_HANDLE> = Vec::with_capacity(max_object_count as usize);
+ let mut count: CK_ULONG = 0;
+ match (self.C_FindObjects)(session, list.as_mut_ptr(), max_object_count, &mut count) {
+ CKR_OK => {
+ unsafe {
+ list.set_len(count as usize);
+ }
+ Ok(list)
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn find_objects_final(&self, session: CK_SESSION_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ match (self.C_FindObjectsFinal)(session) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn encrypt_init(&self, session: CK_SESSION_HANDLE, mechanism: &CK_MECHANISM, key: CK_OBJECT_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ match (self.C_EncryptInit)(session, &mut mechanism, key) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn encrypt(&self, session: CK_SESSION_HANDLE, data: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut data = data.clone();
+ let mut encryptedDataLen: CK_ULONG = 0;
+ match (self.C_Encrypt)(session, data.as_mut_ptr(), data.len() as CK_ULONG, ptr::null_mut(), &mut encryptedDataLen) {
+ CKR_OK => {
+ let mut encryptedData: Vec<CK_BYTE> = Vec::with_capacity(encryptedDataLen as usize);
+ match (self.C_Encrypt)(session, data.as_mut_ptr(), data.len() as CK_ULONG, encryptedData.as_mut_ptr(), &mut encryptedDataLen) {
+ CKR_OK => {
+ unsafe {
+ encryptedData.set_len(encryptedDataLen as usize);
+ }
+ Ok(encryptedData)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn encrypt_update(&self, session: CK_SESSION_HANDLE, part: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut part = part.clone();
+ let mut encryptedPartLen: CK_ULONG = 0;
+ match (self.C_EncryptUpdate)(session, part.as_mut_ptr(), part.len() as CK_ULONG, ptr::null_mut(), &mut encryptedPartLen) {
+ CKR_OK => {
+ let mut encryptedPart: Vec<CK_BYTE> = Vec::with_capacity(encryptedPartLen as usize);
+ match (self.C_EncryptUpdate)(session, part.as_mut_ptr(), part.len() as CK_ULONG, encryptedPart.as_mut_ptr(), &mut encryptedPartLen) {
+ CKR_OK => {
+ unsafe {
+ encryptedPart.set_len(encryptedPartLen as usize);
+ }
+ Ok(encryptedPart)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn encrypt_final(&self, session: CK_SESSION_HANDLE) -> Result<Option<Vec<CK_BYTE>>, Error> {
+ self.initialized()?;
+ let mut lastEncryptedPartLen: CK_ULONG = 0;
+ match (self.C_EncryptFinal)(session, ptr::null_mut(), &mut lastEncryptedPartLen) {
+ CKR_OK => {
+ if lastEncryptedPartLen == 0 {
+ Ok(None)
+ } else {
+ let mut lastEncryptedPart: Vec<CK_BYTE> = Vec::with_capacity(lastEncryptedPartLen as usize);
+ match (self.C_EncryptFinal)(session, lastEncryptedPart.as_mut_ptr(), &mut lastEncryptedPartLen) {
+ CKR_OK => {
+ unsafe {
+ lastEncryptedPart.set_len(lastEncryptedPartLen as usize);
+ }
+ Ok(Some(lastEncryptedPart))
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn decrypt_init(&self, session: CK_SESSION_HANDLE, mechanism: &CK_MECHANISM, key: CK_OBJECT_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ match (self.C_DecryptInit)(session, &mut mechanism, key) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn decrypt(&self, session: CK_SESSION_HANDLE, encryptedData: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut encrypted_data = encryptedData.clone();
+ let mut dataLen: CK_ULONG = 0;
+ match (self.C_Decrypt)(session, encrypted_data.as_mut_ptr(), encrypted_data.len() as CK_ULONG, ptr::null_mut(), &mut dataLen) {
+ CKR_OK => {
+ let mut data: Vec<CK_BYTE> = Vec::with_capacity(dataLen as usize);
+ match (self.C_Decrypt)(session, encrypted_data.as_mut_ptr(), encrypted_data.len() as CK_ULONG, data.as_mut_ptr(), &mut dataLen) {
+ CKR_OK => {
+ unsafe {
+ data.set_len(dataLen as usize);
+ }
+ Ok(data)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn decrypt_update(&self, session: CK_SESSION_HANDLE, encryptedPart: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut encrypted_part = encryptedPart.clone();
+ let mut partLen: CK_ULONG = 0;
+ match (self.C_DecryptUpdate)(session, encrypted_part.as_mut_ptr(), encrypted_part.len() as CK_ULONG, ptr::null_mut(), &mut partLen) {
+ CKR_OK => {
+ let mut part: Vec<CK_BYTE> = Vec::with_capacity(partLen as usize);
+ match (self.C_Decrypt)(session, encrypted_part.as_mut_ptr(), encrypted_part.len() as CK_ULONG, part.as_mut_ptr(), &mut partLen) {
+ CKR_OK => {
+ unsafe {
+ part.set_len(partLen as usize);
+ }
+ Ok(part)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn decrypt_final(&self, session: CK_SESSION_HANDLE) -> Result<Option<Vec<CK_BYTE>>, Error> {
+ self.initialized()?;
+ let mut lastPartLen: CK_ULONG = 0;
+ match (self.C_DecryptFinal)(session, ptr::null_mut(), &mut lastPartLen) {
+ CKR_OK => {
+ if lastPartLen == 0 {
+ Ok(None)
+ } else {
+ let mut lastPart: Vec<CK_BYTE> = Vec::with_capacity(lastPartLen as usize);
+ match (self.C_DecryptFinal)(session, lastPart.as_mut_ptr(), &mut lastPartLen) {
+ CKR_OK => {
+ unsafe {
+ lastPart.set_len(lastPartLen as usize);
+ }
+ Ok(Some(lastPart))
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn digest_init(&self, session: CK_SESSION_HANDLE, mechanism: &CK_MECHANISM) -> Result<(), Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ match (self.C_DigestInit)(session, &mut mechanism) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn digest(&self, session: CK_SESSION_HANDLE, data: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut data = data.clone();
+ let mut digestLen: CK_ULONG = 0;
+ match (self.C_Digest)(session, data.as_mut_ptr(), data.len() as CK_ULONG, ptr::null_mut(), &mut digestLen) {
+ CKR_OK => {
+ let mut digest: Vec<CK_BYTE> = Vec::with_capacity(digestLen as usize);
+ match (self.C_Digest)(session, data.as_mut_ptr(), data.len() as CK_ULONG, digest.as_mut_ptr(), &mut digestLen) {
+ CKR_OK => {
+ unsafe {
+ digest.set_len(digestLen as usize);
+ }
+ Ok(digest)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn digest_update(&self, session: CK_SESSION_HANDLE, part: &Vec<CK_BYTE>) -> Result<(), Error> {
+ let mut part = part.clone();
+ match (self.C_DigestUpdate)(session, part.as_mut_ptr(), part.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn digest_key(&self, session: CK_SESSION_HANDLE, key: CK_OBJECT_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ match (self.C_DigestKey)(session, key) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn digest_final(&self, session: CK_SESSION_HANDLE) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut digestLen: CK_ULONG = 0;
+ match (self.C_DigestFinal)(session, ptr::null_mut(), &mut digestLen) {
+ CKR_OK => {
+ let mut digest: Vec<CK_BYTE> = Vec::with_capacity(digestLen as usize);
+ match (self.C_DigestFinal)(session, digest.as_mut_ptr(), &mut digestLen) {
+ CKR_OK => {
+ unsafe {
+ digest.set_len(digestLen as usize);
+ }
+ Ok(digest)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn sign_init(&self, session: CK_SESSION_HANDLE, mechanism: &CK_MECHANISM, key: CK_OBJECT_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ match (self.C_SignInit)(session, &mut mechanism, key) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn sign(&self, session: CK_SESSION_HANDLE, data: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut data = data.clone();
+ let mut signatureLen: CK_ULONG = 0;
+ match (self.C_Sign)(session, data.as_mut_ptr(), data.len() as CK_ULONG, ptr::null_mut(), &mut signatureLen) {
+ CKR_OK => {
+ let mut signature: Vec<CK_BYTE> = Vec::with_capacity(signatureLen as usize);
+ match (self.C_Sign)(session, data.as_mut_ptr(), data.len() as CK_ULONG, signature.as_mut_ptr(), &mut signatureLen) {
+ CKR_OK => {
+ unsafe {
+ signature.set_len(signatureLen as usize);
+ }
+ Ok(signature)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn sign_update(&self, session: CK_SESSION_HANDLE, part: &Vec<CK_BYTE>) -> Result<(), Error> {
+ self.initialized()?;
+ let mut part = part.clone();
+ match (self.C_SignUpdate)(session, part.as_mut_ptr(), part.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn sign_final(&self, session: CK_SESSION_HANDLE) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut signatureLen: CK_ULONG = 0;
+ match (self.C_SignFinal)(session, ptr::null_mut(), &mut signatureLen) {
+ CKR_OK => {
+ let mut signature: Vec<CK_BYTE> = Vec::with_capacity(signatureLen as usize);
+ match (self.C_SignFinal)(session, signature.as_mut_ptr(), &mut signatureLen) {
+ CKR_OK => {
+ unsafe {
+ signature.set_len(signatureLen as usize);
+ }
+ Ok(signature)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn sign_recover_init(&self, session: CK_SESSION_HANDLE, mechanism: &CK_MECHANISM, key: CK_OBJECT_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ match (self.C_SignRecoverInit)(session, &mut mechanism, key) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err))
+ }
+ }
+
+ pub fn sign_recover(&self, session: CK_SESSION_HANDLE, data: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut data = data.clone();
+ let mut signatureLen: CK_ULONG = 0;
+ match (self.C_SignRecover)(session, data.as_mut_ptr(), data.len() as CK_ULONG, ptr::null_mut(), &mut signatureLen) {
+ CKR_OK => {
+ let mut signature: Vec<CK_BYTE> = Vec::with_capacity(signatureLen as usize);
+ match (self.C_SignRecover)(session, data.as_mut_ptr(), data.len() as CK_ULONG, signature.as_mut_ptr(), &mut signatureLen) {
+ CKR_OK => {
+ unsafe {
+ signature.set_len(signatureLen as usize);
+ }
+ Ok(signature)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn verify_init(&self, session: CK_SESSION_HANDLE, mechanism: &CK_MECHANISM, key: CK_OBJECT_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ match (self.C_VerifyInit)(session, &mut mechanism, key) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn verify(&self, session: CK_SESSION_HANDLE, data: &Vec<CK_BYTE>, signature: &Vec<CK_BYTE>) -> Result<(), Error> {
+ self.initialized()?;
+ let mut data = data.clone();
+ let mut signature = signature.clone();
+ match (self.C_Verify)(session, data.as_mut_ptr(), data.len() as CK_ULONG, signature.as_mut_ptr(), signature.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn verify_update(&self, session: CK_SESSION_HANDLE, part: &Vec<CK_BYTE>) -> Result<(), Error> {
+ self.initialized()?;
+ let mut part = part.clone();
+ match (self.C_VerifyUpdate)(session, part.as_mut_ptr(), part.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn verify_final(&self, session: CK_SESSION_HANDLE, signature: &Vec<CK_BYTE>) -> Result<(), Error> {
+ self.initialized()?;
+ let mut signature = signature.clone();
+ match (self.C_VerifyFinal)(session, signature.as_mut_ptr(), signature.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn verify_recover_init(&self, session: CK_SESSION_HANDLE, mechanism: &CK_MECHANISM, key: CK_OBJECT_HANDLE) -> Result<(), Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ match (self.C_VerifyRecoverInit)(session, &mut mechanism, key) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn verify_recover(&self, session: CK_SESSION_HANDLE, signature: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut signature = signature.clone();
+ let mut dataLen: CK_ULONG = 0;
+ match (self.C_VerifyRecover)(session, signature.as_mut_ptr(), signature.len() as CK_ULONG, ptr::null_mut(), &mut dataLen) {
+ CKR_OK => {
+ let mut data: Vec<CK_BYTE> = Vec::with_capacity(dataLen as usize);
+ match (self.C_VerifyRecover)(session, signature.as_mut_ptr(), signature.len() as CK_ULONG, data.as_mut_ptr(), &mut dataLen) {
+ CKR_OK => {
+ unsafe {
+ data.set_len(dataLen as usize);
+ }
+ Ok(data)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn digest_encrypt_update(&self, session: CK_SESSION_HANDLE, part: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut part = part.clone();
+ let mut encryptedPartLen: CK_ULONG = 0;
+ match (self.C_DigestEncryptUpdate)(session, part.as_mut_ptr(), part.len() as CK_ULONG, ptr::null_mut(), &mut encryptedPartLen) {
+ CKR_OK => {
+ let mut encryptedPart: Vec<CK_BYTE> = Vec::with_capacity(encryptedPartLen as usize);
+ match (self.C_DigestEncryptUpdate)(session, part.as_mut_ptr(), part.len() as CK_ULONG, encryptedPart.as_mut_ptr(), &mut encryptedPartLen) {
+ CKR_OK => {
+ unsafe {
+ encryptedPart.set_len(encryptedPartLen as usize);
+ }
+ Ok(encryptedPart)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn decrypt_digest_update(&self, session: CK_SESSION_HANDLE, encryptedPart: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut encrypted_part = encryptedPart.clone();
+ let mut partLen: CK_ULONG = 0;
+ match (self.C_DecryptDigestUpdate)(session, encrypted_part.as_mut_ptr(), encrypted_part.len() as CK_ULONG, ptr::null_mut(), &mut partLen) {
+ CKR_OK => {
+ let mut part: Vec<CK_BYTE> = Vec::with_capacity(partLen as usize);
+ match (self.C_DecryptDigestUpdate)(session, encrypted_part.as_mut_ptr(), encrypted_part.len() as CK_ULONG, part.as_mut_ptr(), &mut partLen) {
+ CKR_OK => {
+ unsafe {
+ part.set_len(partLen as usize);
+ }
+ Ok(part)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn sign_encrypt_update(&self, session: CK_SESSION_HANDLE, part: &Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut part = part.clone();
+ let mut encryptedPartLen: CK_ULONG = 0;
+ match (self.C_SignEncryptUpdate)(session, part.as_mut_ptr(), part.len() as CK_ULONG, ptr::null_mut(), &mut encryptedPartLen) {
+ CKR_OK => {
+ let mut encryptedPart: Vec<CK_BYTE> = Vec::with_capacity(encryptedPartLen as usize);
+ match (self.C_SignEncryptUpdate)(session, part.as_mut_ptr(), part.len() as CK_ULONG, encryptedPart.as_mut_ptr(), &mut encryptedPartLen) {
+ CKR_OK => {
+ unsafe {
+ encryptedPart.set_len(encryptedPartLen as usize);
+ }
+ Ok(encryptedPart)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn decrypt_verify_update(&self, session: CK_SESSION_HANDLE, encryptedPart: Vec<CK_BYTE>) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut encrypted_part = encryptedPart.clone();
+ let mut partLen: CK_ULONG = 0;
+ match (self.C_DecryptVerifyUpdate)(session, encrypted_part.as_mut_ptr(), encrypted_part.len() as CK_ULONG, ptr::null_mut(), &mut partLen) {
+ CKR_OK => {
+ let mut part: Vec<CK_BYTE> = Vec::with_capacity(partLen as usize);
+ match (self.C_DecryptVerifyUpdate)(session, encrypted_part.as_mut_ptr(), encrypted_part.len() as CK_ULONG, part.as_mut_ptr(), &mut partLen) {
+ CKR_OK => {
+ unsafe {
+ part.set_len(partLen as usize);
+ }
+ Ok(part)
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn generate_key(&self, session: CK_SESSION_HANDLE, mechanism: &CK_MECHANISM, template: &Vec<CK_ATTRIBUTE>) -> Result<CK_OBJECT_HANDLE, Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ let mut template = template.clone();
+ let mut object: CK_OBJECT_HANDLE = CK_INVALID_HANDLE;
+ match (self.C_GenerateKey)(session, &mut mechanism, template.as_mut_ptr(), template.len() as CK_ULONG, &mut object) {
+ CKR_OK => Ok(object),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn generate_key_pair(
+ &self,
+ session: CK_SESSION_HANDLE,
+ mechanism: &CK_MECHANISM,
+ publicKeyTemplate: &Vec<CK_ATTRIBUTE>,
+ privateKeyTemplate: &Vec<CK_ATTRIBUTE>,
+ ) -> Result<(CK_OBJECT_HANDLE, CK_OBJECT_HANDLE), Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ let mut public_key_template = publicKeyTemplate.clone();
+ let mut private_key_template = privateKeyTemplate.clone();
+ let mut pubOh: CK_OBJECT_HANDLE = CK_INVALID_HANDLE;
+ let mut privOh: CK_OBJECT_HANDLE = CK_INVALID_HANDLE;
+ match (self.C_GenerateKeyPair)(
+ session,
+ &mut mechanism,
+ public_key_template.as_mut_ptr(),
+ public_key_template.len() as CK_ULONG,
+ private_key_template.as_mut_ptr(),
+ private_key_template.len() as CK_ULONG,
+ &mut pubOh,
+ &mut privOh,
+ ) {
+ CKR_OK => Ok((pubOh, privOh)),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn wrap_key(&self, session: CK_SESSION_HANDLE, mechanism: &CK_MECHANISM, wrappingKey: CK_OBJECT_HANDLE, key: CK_OBJECT_HANDLE) -> Result<Vec<CK_BYTE>, Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ let mut length: CK_ULONG = 0;
+ match (self.C_WrapKey)(session, &mut mechanism, wrappingKey, key, ptr::null_mut(), &mut length) {
+ CKR_OK => if length > 0 {
+ let mut out: Vec<CK_BYTE> = Vec::with_capacity(length as usize);
+ match (self.C_WrapKey)(session, &mut mechanism, wrappingKey, key, out.as_mut_ptr(), &mut length) {
+ CKR_OK => {
+ unsafe {
+ out.set_len(length as usize);
+ }
+ Ok(out)
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ } else {
+ Ok(vec![])
+ },
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn unwrap_key(
+ &self,
+ session: CK_SESSION_HANDLE,
+ mechanism: &CK_MECHANISM,
+ unwrappingKey: CK_OBJECT_HANDLE,
+ wrappedKey: &Vec<CK_BYTE>,
+ template: &Vec<CK_ATTRIBUTE>,
+ ) -> Result<CK_OBJECT_HANDLE, Error> {
+ self.initialized()?;
+ let mut mechanism= *mechanism;
+ let mut wrapped_key = wrappedKey.clone();
+ let mut template = template.clone();
+ let mut oh: CK_OBJECT_HANDLE = CK_INVALID_HANDLE;
+ match (self.C_UnwrapKey)(
+ session,
+ &mut mechanism,
+ unwrappingKey,
+ wrapped_key.as_mut_ptr(),
+ wrapped_key.len() as CK_ULONG,
+ template.as_mut_ptr(),
+ template.len() as CK_ULONG,
+ &mut oh
+ ) {
+ CKR_OK => Ok(oh),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn derive_key(&self, session: CK_SESSION_HANDLE, mechanism: &CK_MECHANISM, baseKey: CK_OBJECT_HANDLE, template: &Vec<CK_ATTRIBUTE>) -> Result<CK_OBJECT_HANDLE, Error> {
+ self.initialized()?;
+ let mut mechanism = *mechanism;
+ let mut template = template.clone();
+ let mut oh: CK_OBJECT_HANDLE = CK_INVALID_HANDLE;
+ match (self.C_DeriveKey)(session, &mut mechanism, baseKey, template.as_mut_ptr(), template.len() as CK_ULONG, &mut oh) {
+ CKR_OK => Ok(oh),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn seed_random(&self, session: CK_SESSION_HANDLE, seed: &Vec<CK_BYTE>) -> Result<(), Error> {
+ let mut seed = seed.clone();
+ match (self.C_SeedRandom)(session, seed.as_mut_ptr(), seed.len() as CK_ULONG) {
+ CKR_OK => Ok(()),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn generate_random(&self, session: CK_SESSION_HANDLE, randomLength: CK_ULONG) -> Result<Vec<CK_BYTE>, Error> {
+ let mut data: Vec<CK_BYTE> = Vec::with_capacity(randomLength as usize);
+ match (self.C_GenerateRandom)(session, data.as_mut_ptr(), randomLength) {
+ CKR_OK => {
+ unsafe {
+ data.set_len(randomLength as usize);
+ }
+ Ok(data)
+ }
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn get_function_status(&self, session: CK_SESSION_HANDLE) -> Result<CK_RV, Error> {
+ match (self.C_GetFunctionStatus)(session) {
+ CKR_OK => Ok(CKR_OK),
+ CKR_FUNCTION_NOT_PARALLEL => Ok(CKR_FUNCTION_NOT_PARALLEL),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn cancel_function(&self, session: CK_SESSION_HANDLE) -> Result<CK_RV, Error> {
+ match (self.C_CancelFunction)(session) {
+ CKR_OK => Ok(CKR_OK),
+ CKR_FUNCTION_NOT_PARALLEL => Ok(CKR_FUNCTION_NOT_PARALLEL),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+
+ pub fn wait_for_slot_event(&self, flags: CK_FLAGS) -> Result<CK_SLOT_ID, Error> {
+ let mut slotID: CK_SLOT_ID = 0;
+ let C_WaitForSlotEvent = self.C_WaitForSlotEvent.ok_or(Error::Module("C_WaitForSlotEvent function not found"))?;
+ match C_WaitForSlotEvent(flags, &mut slotID, ptr::null_mut()) {
+ CKR_OK => Ok(slotID),
+ err => Err(Error::Pkcs11(err)),
+ }
+ }
+}
+
+impl Drop for Ctx {
+ fn drop(&mut self) {
+ if self.is_initialized() {
+ if let Err(err) = self.finalize() {
+ println!("ERROR: {}", err);
+ }
+ }
+ }
+}
diff --git a/third_party/rust/pkcs11/src/tests.rs b/third_party/rust/pkcs11/src/tests.rs
new file mode 100644
index 0000000000..bc0da16f8c
--- /dev/null
+++ b/third_party/rust/pkcs11/src/tests.rs
@@ -0,0 +1,1552 @@
+// Copyright 2017 Marcus Heese
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+use std::env;
+use std::path::PathBuf;
+
+/// Tests need to be run with `RUST_TEST_THREADS=1` currently to pass.
+extern crate num_traits;
+extern crate hex;
+
+use self::num_traits::Num;
+use self::hex::FromHex;
+
+use super::*;
+use super::types::*;
+use super::errors::Error;
+use num_bigint::BigUint;
+
+fn pkcs11_module_name() -> PathBuf {
+ let default_path = option_env!("PKCS11_SOFTHSM2_MODULE")
+ .unwrap_or("/usr/local/lib/softhsm/libsofthsm2.so");
+ let path = env::var_os("PKCS11_SOFTHSM2_MODULE")
+ .unwrap_or(default_path.into());
+ let path_buf = PathBuf::from(path);
+
+ if !path_buf.exists() {
+ panic!(
+ "Could not find SoftHSM2 at `{}`. Set the `PKCS11_SOFTHSM2_MODULE` environment variable to \
+ its location.",
+ path_buf.display());
+ }
+
+ path_buf
+}
+
+#[test]
+#[serial]
+fn test_label_from_str() {
+ let s30 = "Löwe 老虎 Léopar虎d虎aaa";
+ let s32 = "Löwe 老虎 Léopar虎d虎aaaö";
+ let s33 = "Löwe 老虎 Léopar虎d虎aaa虎";
+ let s34 = "Löwe 老虎 Léopar虎d虎aaab虎";
+ let l30 = label_from_str(s30);
+ let l32 = label_from_str(s32);
+ let l33 = label_from_str(s33);
+ let l34 = label_from_str(s34);
+ println!("Label l30: {:?}", l30);
+ println!("Label l32: {:?}", l32);
+ println!("Label l33: {:?}", l33);
+ println!("Label l34: {:?}", l34);
+ // now the assertions:
+ // - l30 must have the last 2 as byte 32
+ // - l32 must not have any byte 32 at the end
+ // - l33 must have the last 2 as byte 32 because the trailing '虎' is three bytes
+ // - l34 must have hte last 1 as byte 32
+ assert_ne!(l30[29], 32);
+ assert_eq!(l30[30], 32);
+ assert_eq!(l30[31], 32);
+ assert_ne!(l32[31], 32);
+ assert_ne!(l33[29], 32);
+ assert_eq!(l33[30], 32);
+ assert_eq!(l33[31], 32);
+ assert_ne!(l34[30], 32);
+ assert_eq!(l34[31], 32);
+}
+#[test]
+#[serial]
+fn ctx_new() {
+ let res = Ctx::new(pkcs11_module_name());
+ assert!(
+ res.is_ok(),
+ "failed to create new context: {}",
+ res.unwrap_err()
+ );
+}
+
+#[test]
+#[serial]
+fn ctx_initialize() {
+ let mut ctx = Ctx::new(pkcs11_module_name()).unwrap();
+ let res = ctx.initialize(None);
+ assert!(
+ res.is_ok(),
+ "failed to initialize context: {}",
+ res.unwrap_err()
+ );
+ assert!(ctx.is_initialized(), "internal state is not initialized");
+}
+
+#[test]
+#[serial]
+fn ctx_new_and_initialize() {
+ let res = Ctx::new_and_initialize(pkcs11_module_name());
+ assert!(
+ res.is_ok(),
+ "failed to create or initialize new context: {}",
+ res.unwrap_err()
+ );
+}
+
+#[test]
+#[serial]
+fn ctx_finalize() {
+ let mut ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let res = ctx.finalize();
+ assert!(
+ res.is_ok(),
+ "failed to finalize context: {}",
+ res.unwrap_err()
+ );
+}
+
+#[test]
+#[serial]
+fn ctx_get_info() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let res = ctx.get_info();
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetInfo: {}",
+ res.unwrap_err()
+ );
+ let info = res.unwrap();
+ println!("{:?}", info);
+}
+
+#[test]
+#[serial]
+fn ctx_get_function_list() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let res = ctx.get_function_list();
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetFunctionList: {}",
+ res.unwrap_err()
+ );
+ let list = res.unwrap();
+ println!("{:?}", list);
+}
+
+#[test]
+#[serial]
+fn ctx_get_slot_list() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let res = ctx.get_slot_list(false);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetSlotList: {}",
+ res.unwrap_err()
+ );
+ let slots = res.unwrap();
+ println!("Slots: {:?}", slots);
+}
+
+#[test]
+#[serial]
+fn ctx_get_slot_infos() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ let res = ctx.get_slot_info(slot);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetSlotInfo({}): {}",
+ slot,
+ res.unwrap_err()
+ );
+ let info = res.unwrap();
+ println!("Slot {} {:?}", slot, info);
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_get_token_infos() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ let res = ctx.get_token_info(slot);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetTokenInfo({}): {}",
+ slot,
+ res.unwrap_err()
+ );
+ let info = res.unwrap();
+ println!("Slot {} {:?}", slot, info);
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_get_mechanism_lists() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ let res = ctx.get_mechanism_list(slot);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetMechanismList({}): {}",
+ slot,
+ res.unwrap_err()
+ );
+ let mechs = res.unwrap();
+ println!("Slot {} Mechanisms: {:?}", slot, mechs);
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_get_mechanism_infos() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ let mechanisms = ctx.get_mechanism_list(slot).unwrap();
+ for mechanism in mechanisms {
+ let res = ctx.get_mechanism_info(slot, mechanism);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetMechanismInfo({}, {}): {}",
+ slot,
+ mechanism,
+ res.unwrap_err()
+ );
+ let info = res.unwrap();
+ println!("Slot {} Mechanism {}: {:?}", slot, mechanism, info);
+ }
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_init_token() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ let pin = Some("1234");
+ const LABEL: &str = "rust-unit-test";
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ let res = ctx.init_token(slot, pin, LABEL);
+ assert!(
+ res.is_ok(),
+ "failed to call C_InitToken({}, {}, {}): {}",
+ slot,
+ pin.unwrap(),
+ LABEL,
+ res.unwrap_err()
+ );
+ println!(
+ "Slot {} C_InitToken successful, PIN: {}",
+ slot,
+ pin.unwrap()
+ );
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_init_pin() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ let pin = Some("1234");
+ const LABEL: &str = "rust-unit-test";
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ ctx.init_token(slot, pin, LABEL).unwrap();
+ let sh = ctx
+ .open_session(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, None, None)
+ .unwrap();
+ ctx.login(sh, CKU_SO, pin).unwrap();
+ let res = ctx.init_pin(sh, pin);
+ assert!(
+ res.is_ok(),
+ "failed to call C_InitPIN({}, {}): {}",
+ sh,
+ pin.unwrap(),
+ res.unwrap_err()
+ );
+ println!("InitPIN successful");
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_set_pin() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ let pin = Some("1234");
+ let new_pin = Some("1234");
+ const LABEL: &str = "rust-unit-test";
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ ctx.init_token(slot, pin, LABEL).unwrap();
+ let sh = ctx
+ .open_session(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, None, None)
+ .unwrap();
+ ctx.login(sh, CKU_SO, pin).unwrap();
+ let res = ctx.set_pin(sh, pin, new_pin);
+ assert!(
+ res.is_ok(),
+ "failed to call C_SetPIN({}, {}, {}): {}",
+ sh,
+ pin.unwrap(),
+ new_pin.unwrap(),
+ res.unwrap_err()
+ );
+ println!("SetPIN successful");
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_open_session() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ let pin = Some("1234");
+ const LABEL: &str = "rust-unit-test";
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ ctx.init_token(slot, pin, LABEL).unwrap();
+ let res = ctx.open_session(slot, CKF_SERIAL_SESSION, None, None);
+ assert!(
+ res.is_ok(),
+ "failed to call C_OpenSession({}, CKF_SERIAL_SESSION, None, None): {}",
+ slot,
+ res.unwrap_err()
+ );
+ let sh = res.unwrap();
+ println!("Opened Session on Slot {}: CK_SESSION_HANDLE {}", slot, sh);
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_close_session() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ let pin = Some("1234");
+ const LABEL: &str = "rust-unit-test";
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ ctx.init_token(slot, pin, LABEL).unwrap();
+ let sh = ctx
+ .open_session(slot, CKF_SERIAL_SESSION, None, None)
+ .unwrap();
+ let res = ctx.close_session(sh);
+ assert!(
+ res.is_ok(),
+ "failed to call C_CloseSession({}): {}",
+ sh,
+ res.unwrap_err()
+ );
+ println!("Closed Session with CK_SESSION_HANDLE {}", sh);
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_close_all_sessions() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ let pin = Some("1234");
+ const LABEL: &str = "rust-unit-test";
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ ctx.init_token(slot, pin, LABEL).unwrap();
+ ctx
+ .open_session(slot, CKF_SERIAL_SESSION, None, None)
+ .unwrap();
+ let res = ctx.close_all_sessions(slot);
+ assert!(
+ res.is_ok(),
+ "failed to call C_CloseAllSessions({}): {}",
+ slot,
+ res.unwrap_err()
+ );
+ println!("Closed All Sessions on Slot {}", slot);
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_get_session_info() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ let pin = Some("1234");
+ const LABEL: &str = "rust-unit-test";
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ ctx.init_token(slot, pin, LABEL).unwrap();
+ let sh = ctx
+ .open_session(slot, CKF_SERIAL_SESSION, None, None)
+ .unwrap();
+ let res = ctx.get_session_info(sh);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetSessionInfo({}): {}",
+ sh,
+ res.unwrap_err()
+ );
+ let info = res.unwrap();
+ println!("{:?}", info);
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_login() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ let pin = Some("1234");
+ const LABEL: &str = "rust-unit-test";
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ ctx.init_token(slot, pin, LABEL).unwrap();
+ let sh = ctx
+ .open_session(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, None, None)
+ .unwrap();
+ let res = ctx.login(sh, CKU_SO, pin);
+ assert!(
+ res.is_ok(),
+ "failed to call C_Login({}, CKU_SO, {}): {}",
+ sh,
+ pin.unwrap(),
+ res.unwrap_err()
+ );
+ println!("Login successful");
+ }
+}
+
+#[test]
+#[serial]
+fn ctx_logout() {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ let pin = Some("1234");
+ const LABEL: &str = "rust-unit-test";
+ for slot in slots[..1].into_iter() {
+ let slot = *slot;
+ ctx.init_token(slot, pin, LABEL).unwrap();
+ let sh = ctx
+ .open_session(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, None, None)
+ .unwrap();
+ ctx.login(sh, CKU_SO, pin).unwrap();
+ let res = ctx.logout(sh);
+ assert!(
+ res.is_ok(),
+ "failed to call C_Logout({}): {}",
+ sh,
+ res.unwrap_err()
+ );
+ println!("Logout successful");
+ }
+}
+
+#[test]
+fn attr_bool() {
+ let b: CK_BBOOL = CK_FALSE;
+ let attr = CK_ATTRIBUTE::new(CKA_OTP_USER_IDENTIFIER).with_bool(&b);
+ println!("{:?}", attr);
+ let ret: bool = attr.get_bool();
+ println!("{}", ret);
+ assert_eq!(false, ret, "attr.get_bool() should have been false");
+
+ let b: CK_BBOOL = CK_TRUE;
+ let attr = CK_ATTRIBUTE::new(CKA_OTP_USER_IDENTIFIER).with_bool(&b);
+ println!("{:?}", attr);
+ let ret: bool = attr.get_bool();
+ println!("{}", ret);
+ assert_eq!(true, ret, "attr.get_bool() should have been true");
+}
+
+#[test]
+fn attr_ck_ulong() {
+ let val: CK_ULONG = 42;
+ let attr = CK_ATTRIBUTE::new(CKA_RESOLUTION).with_ck_ulong(&val);
+ println!("{:?}", attr);
+ let ret: CK_ULONG = attr.get_ck_ulong();
+ println!("{}", ret);
+ assert_eq!(val, ret, "attr.get_ck_ulong() shouls have been {}", val);
+}
+
+#[test]
+fn attr_ck_long() {
+ let val: CK_LONG = -42;
+ let attr = CK_ATTRIBUTE::new(CKA_RESOLUTION).with_ck_long(&val);
+ println!("{:?}", attr);
+ let ret: CK_LONG = attr.get_ck_long();
+ println!("{}", ret);
+ assert_eq!(val, ret, "attr.get_ck_long() shouls have been {}", val);
+}
+
+#[test]
+fn attr_bytes() {
+ let val = vec![0, 1, 2, 3, 3, 4, 5];
+ let attr = CK_ATTRIBUTE::new(CKA_VALUE).with_bytes(val.as_slice());
+ println!("{:?}", attr);
+ let ret: Vec<CK_BYTE> = attr.get_bytes();
+ println!("{:?}", ret);
+ assert_eq!(
+ val,
+ ret.as_slice(),
+ "attr.get_bytes() shouls have been {:?}",
+ val
+ );
+}
+
+#[test]
+fn attr_string() {
+ let val = String::from("Löwe 老虎");
+ let attr = CK_ATTRIBUTE::new(CKA_LABEL).with_string(&val);
+ println!("{:?}", attr);
+ let ret = attr.get_string();
+ println!("{:?}", ret);
+ assert_eq!(val, ret, "attr.get_string() shouls have been {}", val);
+}
+
+#[test]
+fn attr_date() {
+ let val: CK_DATE = Default::default();
+ let attr = CK_ATTRIBUTE::new(CKA_LABEL).with_date(&val);
+ println!("{:?}", attr);
+ let ret = attr.get_date();
+ println!("{:?}", ret);
+ assert_eq!(
+ val.day,
+ ret.day,
+ "attr.get_date() should have been {:?}",
+ val
+ );
+ assert_eq!(
+ val.month,
+ ret.month,
+ "attr.get_date() should have been {:?}",
+ val
+ );
+ assert_eq!(
+ val.year,
+ ret.year,
+ "attr.get_date() should have been {:?}",
+ val
+ );
+}
+
+#[test]
+fn attr_biginteger() {
+ let num_str = "123456789012345678901234567890123456789012345678901234567890123456789012345678";
+ let val = BigUint::from_str_radix(num_str, 10).unwrap();
+ let slice = val.to_bytes_le();
+ let attr = CK_ATTRIBUTE::new(CKA_LABEL).with_biginteger(&slice);
+ println!("{:?}", attr);
+ let ret = attr.get_biginteger();
+ println!("{:?}", ret);
+ assert_eq!(ret, val, "attr.get_biginteger() should have been {:?}", val);
+ assert_eq!(
+ ret.to_str_radix(10),
+ num_str,
+ "attr.get_biginteger() should have been {:?}",
+ num_str
+ );
+}
+
+/// This will create and initialize a context, set a SO and USER PIN, and login as the USER.
+/// This is the starting point for all tests that are acting on the token.
+/// If you look at the tests here in a "serial" manner, if all the tests are working up until
+/// here, this will always succeed.
+fn fixture_token() -> Result<(Ctx, CK_SESSION_HANDLE), Error> {
+ let ctx = Ctx::new_and_initialize(pkcs11_module_name()).unwrap();
+ let slots = ctx.get_slot_list(false).unwrap();
+ let pin = Some("1234");
+ const LABEL: &str = "rust-unit-test";
+ let slot = *slots.first().ok_or(Error::Module("no slot available"))?;
+ ctx.init_token(slot, pin, LABEL)?;
+ let sh = ctx.open_session(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, None, None)?;
+ ctx.login(sh, CKU_SO, pin)?;
+ ctx.init_pin(sh, pin)?;
+ ctx.logout(sh)?;
+ ctx.login(sh, CKU_USER, pin)?;
+ Ok((ctx, sh))
+}
+
+#[test]
+#[serial]
+fn ctx_create_object() {
+ /*
+ CKA_CLASS ck_type object_class:CKO_DATA
+ CKA_TOKEN bool true
+ CKA_PRIVATE bool true
+ CKA_MODIFIABLE bool true
+ CKA_COPYABLE bool true
+ CKA_LABEL string e4-example
+ CKA_VALUE bytes SGVsbG8gV29ybGQh
+ */
+ let (ctx, sh) = fixture_token().unwrap();
+
+ let class = CKO_DATA;
+ let token: CK_BBOOL = CK_TRUE;
+ let private: CK_BBOOL = CK_TRUE;
+ let modifiable: CK_BBOOL = CK_TRUE;
+ let copyable: CK_BBOOL = CK_TRUE;
+ let label = String::from("rust-unit-test");
+ let value = b"Hello World!";
+
+ let template = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&class),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&token),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&private),
+ CK_ATTRIBUTE::new(CKA_MODIFIABLE).with_bool(&modifiable),
+ CK_ATTRIBUTE::new(CKA_COPYABLE).with_bool(&copyable),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label),
+ CK_ATTRIBUTE::new(CKA_VALUE).with_bytes(&value[..]),
+ ];
+ println!("Template: {:?}", template);
+ let res = ctx.create_object(sh, &template);
+ assert!(
+ res.is_ok(),
+ "failed to call C_CreateObject({}, {:?}): {}",
+ sh,
+ &template,
+ res.is_err()
+ );
+ let oh = res.unwrap();
+ println!("Object Handle: {}", oh);
+}
+
+fn fixture_token_and_object() -> Result<(Ctx, CK_SESSION_HANDLE, CK_OBJECT_HANDLE), Error> {
+ let (ctx, sh) = fixture_token()?;
+
+ let class = CKO_DATA;
+ let token: CK_BBOOL = CK_TRUE;
+ let private: CK_BBOOL = CK_TRUE;
+ let modifiable: CK_BBOOL = CK_TRUE;
+ let copyable: CK_BBOOL = CK_TRUE;
+ let label = String::from("rust-unit-test");
+ let value = b"Hello World!";
+
+ let template = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&class),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&token),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&private),
+ CK_ATTRIBUTE::new(CKA_MODIFIABLE).with_bool(&modifiable),
+ CK_ATTRIBUTE::new(CKA_COPYABLE).with_bool(&copyable),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label),
+ CK_ATTRIBUTE::new(CKA_VALUE).with_bytes(&value[..]),
+ ];
+ let oh = ctx.create_object(sh, &template)?;
+ Ok((ctx, sh, oh))
+}
+
+#[test]
+#[serial]
+fn ctx_copy_object() {
+ let (ctx, sh, oh) = fixture_token_and_object().unwrap();
+
+ let label2 = String::from("rust-unit-test2");
+ let template2 = vec![CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label2)];
+ println!("Template2: {:?}", template2);
+
+ let res = ctx.copy_object(sh, oh, &template2);
+ assert!(
+ res.is_ok(),
+ "failed to call C_CopyObject({}, {}, {:?}): {}",
+ sh,
+ oh,
+ &template2,
+ res.unwrap_err(),
+ );
+ let oh2 = res.unwrap();
+ println!("Object Handle2: {}", oh2);
+}
+
+#[test]
+#[serial]
+fn ctx_destroy_object() {
+ let (ctx, sh, oh) = fixture_token_and_object().unwrap();
+
+ let res = ctx.destroy_object(sh, oh);
+ assert!(
+ res.is_ok(),
+ "failed to call C_DestroyObject({}, {}): {})",
+ sh,
+ oh,
+ res.unwrap_err()
+ );
+}
+
+#[test]
+#[serial]
+fn ctx_get_object_size() {
+ let (ctx, sh, oh) = fixture_token_and_object().unwrap();
+
+ let res = ctx.get_object_size(sh, oh);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetObjectSize({}, {}): {}",
+ sh,
+ oh,
+ res.unwrap_err()
+ );
+ let size = res.unwrap();
+ println!("Object Size: {}", size);
+}
+
+#[test]
+#[serial]
+fn ctx_get_attribute_value() {
+ {
+ let (ctx, sh, oh) = fixture_token_and_object().unwrap();
+
+ let mut template = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS),
+ CK_ATTRIBUTE::new(CKA_PRIVATE),
+ CK_ATTRIBUTE::new(CKA_LABEL),
+ CK_ATTRIBUTE::new(CKA_VALUE),
+ ];
+ println!("Template: {:?}", template);
+ {
+ let res = ctx.get_attribute_value(sh, oh, &template);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetAttributeValue({}, {}, {:?}): {}",
+ sh,
+ oh,
+ &template,
+ res.unwrap_err()
+ );
+ let (rv, _) = res.unwrap();
+ println!("CK_RV: 0x{:x}, Template: {:?}", rv, &template);
+ }
+
+ let class: CK_ULONG = 0;
+ let private: CK_BBOOL = 1;
+ let label: String = String::with_capacity(template[2].ulValueLen);
+ let value: Vec<CK_BYTE> = Vec::with_capacity(template[3].ulValueLen);
+ template[0].set_ck_ulong(&class);
+ template[1].set_bool(&private);
+ template[2].set_string(&label);
+ template[3].set_bytes(&value.as_slice());
+
+ let res = ctx.get_attribute_value(sh, oh, &template);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetAttributeValue({}, {}, {:?}): {}",
+ sh,
+ oh,
+ &template,
+ res.unwrap_err()
+ );
+ let (rv, _) = res.unwrap();
+ println!("CK_RV: 0x{:x}, Retrieved Attributes: {:?}", rv, &template);
+
+ assert_eq!(CKO_DATA, template[0].get_ck_ulong());
+ assert_eq!(true, template[1].get_bool());
+ assert_eq!(String::from("rust-unit-test"), template[2].get_string());
+ assert_eq!(Vec::from("Hello World!"), template[3].get_bytes());
+ }
+ println!("The end");
+}
+
+#[test]
+#[serial]
+fn ctx_set_attribute_value() {
+ let (ctx, sh, oh) = fixture_token_and_object().unwrap();
+
+ let value = b"Hello New World!";
+ let template = vec![CK_ATTRIBUTE::new(CKA_LABEL).with_bytes(&value[..])];
+
+ let res = ctx.set_attribute_value(sh, oh, &template);
+ assert!(
+ res.is_ok(),
+ "failed to call C_SetAttributeValue({}, {}, {:?}): {}",
+ sh,
+ oh,
+ &template,
+ res.unwrap_err()
+ );
+
+ let str: Vec<CK_BYTE> = Vec::from("aaaaaaaaaaaaaaaa");
+ let template2 = vec![CK_ATTRIBUTE::new(CKA_LABEL).with_bytes(&str.as_slice())];
+ ctx.get_attribute_value(sh, oh, &template2).unwrap();
+ assert_eq!(Vec::from("Hello New World!"), template2[0].get_bytes());
+}
+
+#[test]
+#[serial]
+fn ctx_find_objects_init() {
+ let (ctx, sh, _) = fixture_token_and_object().unwrap();
+
+ let label = String::from("rust-unit-test");
+ let template = vec![CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label)];
+
+ let res = ctx.find_objects_init(sh, &template);
+ assert!(
+ res.is_ok(),
+ "failed to call C_FindObjectsInit({}, {:?}): {}",
+ sh,
+ &template,
+ res.unwrap_err()
+ );
+}
+
+#[test]
+#[serial]
+fn ctx_find_objects() {
+ let (ctx, sh, _) = fixture_token_and_object().unwrap();
+
+ let label = String::from("rust-unit-test");
+ let template = vec![CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label)];
+
+ ctx.find_objects_init(sh, &template).unwrap();
+
+ let res = ctx.find_objects(sh, 10);
+ assert!(
+ res.is_ok(),
+ "failed to call C_FindObjects({}, {}): {}",
+ sh,
+ 10,
+ res.unwrap_err()
+ );
+ let objs = res.unwrap();
+ assert_eq!(objs.len(), 1);
+}
+
+#[test]
+#[serial]
+fn ctx_find_objects_final() {
+ let (ctx, sh, _) = fixture_token_and_object().unwrap();
+
+ let label = String::from("rust-unit-test");
+ let template = vec![CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label)];
+
+ ctx.find_objects_init(sh, &template).unwrap();
+ ctx.find_objects(sh, 10).unwrap();
+
+ let res = ctx.find_objects_final(sh);
+ assert!(
+ res.is_ok(),
+ "failed to call C_FindObjectsFinal({}): {}",
+ sh,
+ res.unwrap_err()
+ );
+}
+
+#[test]
+#[serial]
+fn ctx_generate_key() {
+ let (ctx, sh) = fixture_token().unwrap();
+
+ let mechanism = CK_MECHANISM {
+ mechanism: CKM_AES_KEY_GEN,
+ pParameter: ptr::null(),
+ ulParameterLen: 0,
+ };
+
+ // Wrapping Key Template:
+ // CKA_CLASS ck_type object_class:CKO_SECRET_KEY
+ // CKA_KEY_TYPE ck_type key_type:CKK_AES
+ // CKA_TOKEN bool true
+ // CKA_LABEL string wrap1-wrap-key
+ // CKA_ENCRYPT bool false
+ // CKA_DECRYPT bool false
+ // CKA_VALUE_LEN uint 32
+ // CKA_PRIVATE bool true
+ // CKA_SENSITIVE bool false
+ // CKA_EXTRACTABLE bool true
+ // CKA_WRAP bool true
+ // CKA_UNWRAP bool true
+
+ let class = CKO_SECRET_KEY;
+ let keyType = CKK_AES;
+ let valueLen = 32;
+ let label = String::from("wrap1-wrap-key");
+ let token: CK_BBOOL = CK_TRUE;
+ let private: CK_BBOOL = CK_TRUE;
+ let encrypt: CK_BBOOL = CK_FALSE;
+ let decrypt: CK_BBOOL = CK_FALSE;
+ let sensitive: CK_BBOOL = CK_FALSE;
+ let extractable: CK_BBOOL = CK_TRUE;
+ let wrap: CK_BBOOL = CK_TRUE;
+ let unwrap: CK_BBOOL = CK_TRUE;
+
+ let template = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&class),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&keyType),
+ CK_ATTRIBUTE::new(CKA_VALUE_LEN).with_ck_ulong(&valueLen),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&token),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&private),
+ CK_ATTRIBUTE::new(CKA_ENCRYPT).with_bool(&encrypt),
+ CK_ATTRIBUTE::new(CKA_DECRYPT).with_bool(&decrypt),
+ CK_ATTRIBUTE::new(CKA_SENSITIVE).with_bool(&sensitive),
+ CK_ATTRIBUTE::new(CKA_EXTRACTABLE).with_bool(&extractable),
+ CK_ATTRIBUTE::new(CKA_WRAP).with_bool(&wrap),
+ CK_ATTRIBUTE::new(CKA_UNWRAP).with_bool(&unwrap),
+ ];
+
+ let res = ctx.generate_key(sh, &mechanism, &template);
+ assert!(
+ res.is_ok(),
+ "failed to call C_Generatekey({}, {:?}, {:?}): {}",
+ sh,
+ mechanism,
+ template,
+ res.unwrap_err()
+ );
+ let oh = res.unwrap();
+ assert_ne!(oh, CK_INVALID_HANDLE);
+ println!("Generated Key Object Handle: {}", oh);
+}
+
+#[test]
+#[serial]
+fn ctx_generate_key_pair() {
+ let (ctx, sh) = fixture_token().unwrap();
+
+ let mechanism = CK_MECHANISM {
+ mechanism: CKM_RSA_PKCS_KEY_PAIR_GEN,
+ pParameter: ptr::null(),
+ ulParameterLen: 0,
+ };
+
+ // Private Key Template
+ // CKA_CLASS ck_type object_class:CKO_PRIVATE_KEY
+ // CKA_KEY_TYPE ck_type key_type:CKK_RSA
+ // CKA_TOKEN bool true
+ // CKA_SENSITIVE bool true
+ // CKA_UNWRAP bool false
+ // CKA_EXTRACTABLE bool false
+ // CKA_LABEL string ca-hsm-priv
+ // CKA_SIGN bool true
+ // CKA_PRIVATE bool true
+
+ let privClass = CKO_PRIVATE_KEY;
+ let privKeyType = CKK_RSA;
+ let privLabel = String::from("ca-hsm-priv");
+ let privToken = CK_TRUE;
+ let privPrivate = CK_TRUE;
+ let privSensitive = CK_TRUE;
+ let privUnwrap = CK_FALSE;
+ let privExtractable = CK_FALSE;
+ let privSign = CK_TRUE;
+
+ let privTemplate = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&privClass),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&privKeyType),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&privLabel),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&privToken),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&privPrivate),
+ CK_ATTRIBUTE::new(CKA_SENSITIVE).with_bool(&privSensitive),
+ CK_ATTRIBUTE::new(CKA_UNWRAP).with_bool(&privUnwrap),
+ CK_ATTRIBUTE::new(CKA_EXTRACTABLE).with_bool(&privExtractable),
+ CK_ATTRIBUTE::new(CKA_SIGN).with_bool(&privSign),
+ ];
+
+ // Public Key Template
+ // CKA_CLASS ck_type object_class:CKO_PUBLIC_KEY
+ // CKA_KEY_TYPE ck_type key_type:CKK_RSA
+ // CKA_TOKEN bool true
+ // CKA_MODULUS_BITS uint 4096
+ // CKA_PUBLIC_EXPONENT big_integer 65537
+ // CKA_LABEL string ca-hsm-pub
+ // CKA_WRAP bool false
+ // CKA_VERIFY bool true
+ // CKA_PRIVATE bool true
+
+ let pubClass = CKO_PUBLIC_KEY;
+ let pubKeyType = CKK_RSA;
+ let pubLabel = String::from("ca-hsm-pub");
+ let pubToken = CK_TRUE;
+ let pubPrivate = CK_TRUE;
+ let pubWrap = CK_FALSE;
+ let pubVerify = CK_TRUE;
+ let pubModulusBits: CK_ULONG = 4096;
+ let pubPublicExponent = BigUint::from(65537u32);
+ let pubPublicExponentSlice = pubPublicExponent.to_bytes_le();
+
+ let pubTemplate = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&pubClass),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&pubKeyType),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&pubLabel),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&pubToken),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&pubPrivate),
+ CK_ATTRIBUTE::new(CKA_WRAP).with_bool(&pubWrap),
+ CK_ATTRIBUTE::new(CKA_VERIFY).with_bool(&pubVerify),
+ CK_ATTRIBUTE::new(CKA_MODULUS_BITS).with_ck_ulong(&pubModulusBits),
+ CK_ATTRIBUTE::new(CKA_PUBLIC_EXPONENT).with_biginteger(&pubPublicExponentSlice),
+ ];
+
+ let res = ctx.generate_key_pair(sh, &mechanism, &pubTemplate, &privTemplate);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GenerateKeyPair({}, {:?}, {:?}, {:?}): {}",
+ sh,
+ &mechanism,
+ &pubTemplate,
+ &privTemplate,
+ res.unwrap_err()
+ );
+ let (pubOh, privOh) = res.unwrap();
+ println!("Private Key Object Handle: {}", privOh);
+ println!("Public Key Object Handle: {}", pubOh);
+}
+
+fn fixture_token_and_secret_keys(
+) -> Result<(Ctx, CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE), Error> {
+ let (ctx, sh) = fixture_token()?;
+
+ let wrapOh: CK_OBJECT_HANDLE;
+ let secOh: CK_OBJECT_HANDLE;
+ {
+ let mechanism = CK_MECHANISM {
+ mechanism: CKM_AES_KEY_GEN,
+ pParameter: ptr::null(),
+ ulParameterLen: 0,
+ };
+
+ let class = CKO_SECRET_KEY;
+ let keyType = CKK_AES;
+ let valueLen = 32;
+ let label = String::from("wrap1-wrap-key");
+ let token: CK_BBOOL = CK_TRUE;
+ let private: CK_BBOOL = CK_TRUE;
+ let encrypt: CK_BBOOL = CK_FALSE;
+ let decrypt: CK_BBOOL = CK_FALSE;
+ let sensitive: CK_BBOOL = CK_FALSE;
+ let extractable: CK_BBOOL = CK_TRUE;
+ let wrap: CK_BBOOL = CK_TRUE;
+ let unwrap: CK_BBOOL = CK_TRUE;
+
+ let template = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&class),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&keyType),
+ CK_ATTRIBUTE::new(CKA_VALUE_LEN).with_ck_ulong(&valueLen),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&token),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&private),
+ CK_ATTRIBUTE::new(CKA_ENCRYPT).with_bool(&encrypt),
+ CK_ATTRIBUTE::new(CKA_DECRYPT).with_bool(&decrypt),
+ CK_ATTRIBUTE::new(CKA_SENSITIVE).with_bool(&sensitive),
+ CK_ATTRIBUTE::new(CKA_EXTRACTABLE).with_bool(&extractable),
+ CK_ATTRIBUTE::new(CKA_WRAP).with_bool(&wrap),
+ CK_ATTRIBUTE::new(CKA_UNWRAP).with_bool(&unwrap),
+ ];
+
+ wrapOh = ctx.generate_key(sh, &mechanism, &template)?;
+ }
+
+ {
+ let mechanism = CK_MECHANISM {
+ mechanism: CKM_AES_KEY_GEN,
+ pParameter: ptr::null(),
+ ulParameterLen: 0,
+ };
+
+ // CKA_CLASS ck_type object_class:CKO_SECRET_KEY
+ // CKA_KEY_TYPE ck_type key_type:CKK_AES
+ // CKA_TOKEN bool true
+ // CKA_LABEL string secured-key
+ // CKA_ENCRYPT bool true
+ // CKA_DECRYPT bool true
+ // CKA_VALUE_LEN uint 32
+ // CKA_PRIVATE bool true
+ // CKA_SENSITIVE bool true
+ // CKA_EXTRACTABLE bool true
+ // CKA_WRAP bool false
+ // CKA_UNWRAP bool false
+
+ let class = CKO_SECRET_KEY;
+ let keyType = CKK_AES;
+ let valueLen = 32;
+ let label = String::from("secured-key");
+ let token: CK_BBOOL = CK_TRUE;
+ let private: CK_BBOOL = CK_TRUE;
+ let encrypt: CK_BBOOL = CK_TRUE;
+ let decrypt: CK_BBOOL = CK_TRUE;
+ let sensitive: CK_BBOOL = CK_TRUE;
+ let extractable: CK_BBOOL = CK_TRUE;
+ let wrap: CK_BBOOL = CK_FALSE;
+ let unwrap: CK_BBOOL = CK_FALSE;
+
+ let template = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&class),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&keyType),
+ CK_ATTRIBUTE::new(CKA_VALUE_LEN).with_ck_ulong(&valueLen),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&token),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&private),
+ CK_ATTRIBUTE::new(CKA_ENCRYPT).with_bool(&encrypt),
+ CK_ATTRIBUTE::new(CKA_DECRYPT).with_bool(&decrypt),
+ CK_ATTRIBUTE::new(CKA_SENSITIVE).with_bool(&sensitive),
+ CK_ATTRIBUTE::new(CKA_EXTRACTABLE).with_bool(&extractable),
+ CK_ATTRIBUTE::new(CKA_WRAP).with_bool(&wrap),
+ CK_ATTRIBUTE::new(CKA_UNWRAP).with_bool(&unwrap),
+ ];
+
+ secOh = ctx.generate_key(sh, &mechanism, &template)?;
+ }
+
+ Ok((ctx, sh, wrapOh, secOh))
+}
+
+#[allow(dead_code)]
+fn fixture_key_pair(
+ ctx: &Ctx,
+ sh: CK_SESSION_HANDLE,
+ pubLabel: String,
+ privLabel: String,
+) -> Result<(CK_OBJECT_HANDLE, CK_OBJECT_HANDLE), Error> {
+ let mechanism = CK_MECHANISM {
+ mechanism: CKM_RSA_PKCS_KEY_PAIR_GEN,
+ pParameter: ptr::null(),
+ ulParameterLen: 0,
+ };
+
+ let privClass = CKO_PRIVATE_KEY;
+ let privKeyType = CKK_RSA;
+ let privLabel = privLabel;
+ let privToken = CK_TRUE;
+ let privPrivate = CK_TRUE;
+ let privSensitive = CK_TRUE;
+ let privUnwrap = CK_FALSE;
+ let privExtractable = CK_FALSE;
+ let privSign = CK_TRUE;
+
+ let privTemplate = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&privClass),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&privKeyType),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&privLabel),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&privToken),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&privPrivate),
+ CK_ATTRIBUTE::new(CKA_SENSITIVE).with_bool(&privSensitive),
+ CK_ATTRIBUTE::new(CKA_UNWRAP).with_bool(&privUnwrap),
+ CK_ATTRIBUTE::new(CKA_EXTRACTABLE).with_bool(&privExtractable),
+ CK_ATTRIBUTE::new(CKA_SIGN).with_bool(&privSign),
+ ];
+
+ let pubClass = CKO_PUBLIC_KEY;
+ let pubKeyType = CKK_RSA;
+ let pubLabel = pubLabel;
+ let pubToken = CK_TRUE;
+ let pubPrivate = CK_TRUE;
+ let pubWrap = CK_FALSE;
+ let pubVerify = CK_TRUE;
+ let pubModulusBits: CK_ULONG = 4096;
+ let pubPublicExponent = BigUint::from(65537u32);
+ let pubPublicExponentSlice = pubPublicExponent.to_bytes_le();
+
+ let pubTemplate = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&pubClass),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&pubKeyType),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&pubLabel),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&pubToken),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&pubPrivate),
+ CK_ATTRIBUTE::new(CKA_WRAP).with_bool(&pubWrap),
+ CK_ATTRIBUTE::new(CKA_VERIFY).with_bool(&pubVerify),
+ CK_ATTRIBUTE::new(CKA_MODULUS_BITS).with_ck_ulong(&pubModulusBits),
+ CK_ATTRIBUTE::new(CKA_PUBLIC_EXPONENT).with_biginteger(&pubPublicExponentSlice),
+ ];
+
+ let (pubOh, privOh) = ctx.generate_key_pair(sh, &mechanism, &pubTemplate, &privTemplate)?;
+ Ok((pubOh, privOh))
+}
+
+fn fixture_dh_key_pair(
+ ctx: &Ctx,
+ sh: CK_SESSION_HANDLE,
+ pubLabel: String,
+ privLabel: String,
+) -> Result<(CK_OBJECT_HANDLE, CK_OBJECT_HANDLE), Error> {
+ let mechanism = CK_MECHANISM {
+ mechanism: CKM_DH_PKCS_KEY_PAIR_GEN,
+ pParameter: ptr::null(),
+ ulParameterLen: 0,
+ };
+ //[]*pkcs11.Attribute{
+ // pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
+ // pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_DH),
+ // pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),
+ // pkcs11.NewAttribute(pkcs11.CKA_TOKEN, false),
+ // pkcs11.NewAttribute(pkcs11.CKA_DERIVE, true),
+ //},
+ let privClass = CKO_PRIVATE_KEY;
+ let privKeyType = CKK_DH;
+ let privLabel = privLabel;
+ let privToken = CK_TRUE;
+ let privPrivate = CK_TRUE;
+ let privSensitive = CK_TRUE;
+ let privExtractable = CK_FALSE;
+ let privDerive = CK_TRUE;
+
+ let privTemplate = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&privClass),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&privKeyType),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&privLabel),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&privToken),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&privPrivate),
+ CK_ATTRIBUTE::new(CKA_SENSITIVE).with_bool(&privSensitive),
+ CK_ATTRIBUTE::new(CKA_EXTRACTABLE).with_bool(&privExtractable),
+ CK_ATTRIBUTE::new(CKA_DERIVE).with_bool(&privDerive),
+ ];
+
+ /*
+ []*pkcs11.Attribute{
+ pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
+ pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_DH),
+ pkcs11.NewAttribute(pkcs11.CKA_PRIVATE, true),
+ pkcs11.NewAttribute(pkcs11.CKA_TOKEN, false),
+ pkcs11.NewAttribute(pkcs11.CKA_DERIVE, true),
+ pkcs11.NewAttribute(pkcs11.CKA_BASE, domainParamBase.Bytes()),
+ pkcs11.NewAttribute(pkcs11.CKA_PRIME, domainParamPrime.Bytes()),
+ },
+ */
+
+ let pubClass = CKO_PUBLIC_KEY;
+ let pubKeyType = CKK_DH;
+ let pubLabel = pubLabel;
+ let pubToken = CK_TRUE;
+ let pubPrivate = CK_TRUE;
+ let pubDerive = CK_TRUE;
+ // 2048-bit MODP Group
+ let prime: Vec<u8> = Vec::from_hex(
+ "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF",
+ ).unwrap();
+ // 1536-bit MODP Group
+ //let base: Vec<u8> = Vec::from_hex(
+ // "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
+ //).unwrap();
+ let base: Vec<u8> = Vec::from_hex("02").unwrap();
+
+ let pubTemplate = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&pubClass),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&pubKeyType),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&pubLabel),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&pubToken),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&pubPrivate),
+ CK_ATTRIBUTE::new(CKA_DERIVE).with_bool(&pubDerive),
+ CK_ATTRIBUTE::new(CKA_BASE).with_bytes(&base.as_slice()),
+ CK_ATTRIBUTE::new(CKA_PRIME).with_bytes(&prime.as_slice()),
+ ];
+
+ let (pubOh, privOh) = ctx.generate_key_pair(sh, &mechanism, &pubTemplate, &privTemplate)?;
+ Ok((pubOh, privOh))
+}
+
+#[test]
+#[serial]
+fn ctx_wrap_key() {
+ let (ctx, sh, wrapOh, secOh) = fixture_token_and_secret_keys().unwrap();
+
+ // using the default IV
+ let mechanism = CK_MECHANISM {
+ mechanism: CKM_AES_KEY_WRAP_PAD,
+ pParameter: ptr::null(),
+ ulParameterLen: 0,
+ };
+
+ let res = ctx.wrap_key(sh, &mechanism, wrapOh, secOh);
+ assert!(
+ res.is_ok(),
+ "failed to call C_WrapKey({}, {:?}, {}, {}) without parameter: {}",
+ sh,
+ &mechanism,
+ wrapOh,
+ secOh,
+ res.unwrap_err()
+ );
+ let wrappedKey = res.unwrap();
+ println!(
+ "Wrapped Key Bytes (Total of {} bytes): {:?}",
+ wrappedKey.len(),
+ wrappedKey
+ );
+}
+
+#[test]
+#[serial]
+fn ctx_unwrap_key() {
+ let (ctx, sh, wrapOh, secOh) = fixture_token_and_secret_keys().unwrap();
+
+ // using the default IV
+ let mechanism = CK_MECHANISM {
+ mechanism: CKM_AES_KEY_WRAP_PAD,
+ pParameter: ptr::null(),
+ ulParameterLen: 0,
+ };
+
+ let wrappedKey = ctx.wrap_key(sh, &mechanism, wrapOh, secOh).unwrap();
+
+ let class = CKO_SECRET_KEY;
+ let keyType = CKK_AES;
+ let label = String::from("secured-key-unwrapped");
+ let token: CK_BBOOL = CK_TRUE;
+ let private: CK_BBOOL = CK_TRUE;
+ let encrypt: CK_BBOOL = CK_TRUE;
+ let decrypt: CK_BBOOL = CK_TRUE;
+ let sensitive: CK_BBOOL = CK_TRUE;
+ let extractable: CK_BBOOL = CK_TRUE;
+ let wrap: CK_BBOOL = CK_FALSE;
+ let unwrap: CK_BBOOL = CK_FALSE;
+
+ let template = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&class),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&keyType),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&token),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&private),
+ CK_ATTRIBUTE::new(CKA_ENCRYPT).with_bool(&encrypt),
+ CK_ATTRIBUTE::new(CKA_DECRYPT).with_bool(&decrypt),
+ CK_ATTRIBUTE::new(CKA_SENSITIVE).with_bool(&sensitive),
+ CK_ATTRIBUTE::new(CKA_EXTRACTABLE).with_bool(&extractable),
+ CK_ATTRIBUTE::new(CKA_WRAP).with_bool(&wrap),
+ CK_ATTRIBUTE::new(CKA_UNWRAP).with_bool(&unwrap),
+ ];
+
+ let res = ctx.unwrap_key(sh, &mechanism, wrapOh, &wrappedKey, &template);
+ assert!(
+ res.is_ok(),
+ "failed to call C_UnwrapKey({}, {:?}, {}, {:?}, {:?}): {}",
+ sh,
+ &mechanism,
+ wrapOh,
+ &wrappedKey,
+ &template,
+ res.unwrap_err()
+ );
+ let oh = res.unwrap();
+ println!("New unwrapped key Object Handle: {}", oh);
+}
+
+#[test]
+#[serial]
+fn ctx_derive_key() {
+ let (ctx, sh) = fixture_token().unwrap();
+
+ // 1. generate 2 DH KeyPairs
+ let (pubOh1, privOh1) = fixture_dh_key_pair(
+ &ctx,
+ sh,
+ String::from("label1-pub"),
+ String::from("label1-priv"),
+ ).unwrap();
+ let (pubOh2, privOh2) = fixture_dh_key_pair(
+ &ctx,
+ sh,
+ String::from("label2-pub"),
+ String::from("label2-priv"),
+ ).unwrap();
+
+ // 2. retrieve the public key bytes from both
+ let mut template = vec![CK_ATTRIBUTE::new(CKA_VALUE)];
+ ctx.get_attribute_value(sh, pubOh1, &template).unwrap();
+ let value: Vec<CK_BYTE> = Vec::with_capacity(template[0].ulValueLen);
+ template[0].set_bytes(&value.as_slice());
+ ctx.get_attribute_value(sh, pubOh1, &template).unwrap();
+
+ let pub1Bytes = template[0].get_bytes();
+
+ let mut template = vec![CK_ATTRIBUTE::new(CKA_VALUE)];
+ ctx.get_attribute_value(sh, pubOh2, &template).unwrap();
+ let value: Vec<CK_BYTE> = Vec::with_capacity(template[0].ulValueLen);
+ template[0].set_bytes(&value.as_slice());
+ ctx.get_attribute_value(sh, pubOh2, &template).unwrap();
+
+ let pub2Bytes = template[0].get_bytes();
+
+ // 3. derive the first secret key
+ let mechanism = CK_MECHANISM {
+ mechanism: CKM_DH_PKCS_DERIVE,
+ pParameter: pub2Bytes.as_slice().as_ptr() as CK_VOID_PTR,
+ ulParameterLen: pub2Bytes.len(),
+ };
+
+ let class = CKO_SECRET_KEY;
+ let keyType = CKK_AES;
+ let valueLen = 32;
+ let label = String::from("derived-key-1");
+ let token: CK_BBOOL = CK_TRUE;
+ let private: CK_BBOOL = CK_TRUE;
+ let sensitive: CK_BBOOL = CK_FALSE;
+ let extractable: CK_BBOOL = CK_TRUE;
+
+ let template = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&class),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&keyType),
+ CK_ATTRIBUTE::new(CKA_VALUE_LEN).with_ck_ulong(&valueLen),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&token),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&private),
+ CK_ATTRIBUTE::new(CKA_SENSITIVE).with_bool(&sensitive),
+ CK_ATTRIBUTE::new(CKA_EXTRACTABLE).with_bool(&extractable),
+ ];
+
+ let res = ctx.derive_key(sh, &mechanism, privOh1, &template);
+ assert!(res.is_ok(), "failed to call C_DeriveKey({}, {:?}, {}, {:?}): {}", sh, &mechanism, privOh1, &template, res.unwrap_err());
+ let secOh1 = res.unwrap();
+ println!("1st Derived Secret Key Object Handle: {}", secOh1);
+
+ // 4. derive the second secret key
+ let mechanism = CK_MECHANISM {
+ mechanism: CKM_DH_PKCS_DERIVE,
+ pParameter: pub1Bytes.as_slice().as_ptr() as CK_VOID_PTR,
+ ulParameterLen: pub1Bytes.len(),
+ };
+
+ let class = CKO_SECRET_KEY;
+ let keyType = CKK_AES;
+ let valueLen = 32;
+ let label = String::from("derived-key-2");
+ let token: CK_BBOOL = CK_TRUE;
+ let private: CK_BBOOL = CK_TRUE;
+ let sensitive: CK_BBOOL = CK_FALSE;
+ let extractable: CK_BBOOL = CK_TRUE;
+
+ let template = vec![
+ CK_ATTRIBUTE::new(CKA_CLASS).with_ck_ulong(&class),
+ CK_ATTRIBUTE::new(CKA_KEY_TYPE).with_ck_ulong(&keyType),
+ CK_ATTRIBUTE::new(CKA_VALUE_LEN).with_ck_ulong(&valueLen),
+ CK_ATTRIBUTE::new(CKA_LABEL).with_string(&label),
+ CK_ATTRIBUTE::new(CKA_TOKEN).with_bool(&token),
+ CK_ATTRIBUTE::new(CKA_PRIVATE).with_bool(&private),
+ CK_ATTRIBUTE::new(CKA_SENSITIVE).with_bool(&sensitive),
+ CK_ATTRIBUTE::new(CKA_EXTRACTABLE).with_bool(&extractable),
+ ];
+
+ let res = ctx.derive_key(sh, &mechanism, privOh2, &template);
+ assert!(res.is_ok(), "failed to call C_DeriveKey({}, {:?}, {}, {:?}): {}", sh, &mechanism, privOh2, &template, res.unwrap_err());
+ let secOh2 = res.unwrap();
+ println!("2nd Derived Secret Key Object Handle: {}", secOh2);
+
+ // 5. retrieve the derived private keys from both
+ let mut template = vec![CK_ATTRIBUTE::new(CKA_VALUE)];
+ ctx.get_attribute_value(sh, secOh1, &template).unwrap();
+ let value: Vec<CK_BYTE> = Vec::with_capacity(template[0].ulValueLen);
+ template[0].set_bytes(&value.as_slice());
+ ctx.get_attribute_value(sh, secOh1, &template).unwrap();
+
+ let sec1Bytes = template[0].get_bytes();
+
+ let mut template = vec![CK_ATTRIBUTE::new(CKA_VALUE)];
+ ctx.get_attribute_value(sh, secOh2, &template).unwrap();
+ let value: Vec<CK_BYTE> = Vec::with_capacity(template[0].ulValueLen);
+ template[0].set_bytes(&value.as_slice());
+ ctx.get_attribute_value(sh, secOh2, &template).unwrap();
+
+ let sec2Bytes = template[0].get_bytes();
+
+ println!("1st Derived Key Bytes: {:?}", sec1Bytes);
+ println!("2nd Derived Key Bytes: {:?}", sec2Bytes);
+ assert_eq!(sec1Bytes, sec2Bytes, "Derived Secret Keys don't match");
+}
+
+#[test]
+#[serial]
+fn ctx_seed_random() {
+ let (ctx, sh) = fixture_token().unwrap();
+
+ let seed: Vec<CK_BYTE> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+ let res = ctx.seed_random(sh, &seed);
+ assert!(
+ res.is_ok(),
+ "failed to call C_SeedRandom({}, {:?}): {}",
+ sh,
+ &seed,
+ res.unwrap_err()
+ );
+}
+
+#[test]
+#[serial]
+fn ctx_generate_random() {
+ let (ctx, sh) = fixture_token().unwrap();
+ let res = ctx.generate_random(sh, 32);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GenerateRandom({}, {}): {}",
+ sh,
+ 32,
+ res.unwrap_err()
+ );
+ let randomData = res.unwrap();
+ println!("Randomly Generated Data: {:?}", randomData);
+}
+
+#[test]
+#[serial]
+fn ctx_get_function_status() {
+ let (ctx, sh) = fixture_token().unwrap();
+ let res = ctx.get_function_status(sh);
+ assert!(
+ res.is_ok(),
+ "failed to call C_GetFunctionStatus({}): {}",
+ sh,
+ res.unwrap_err()
+ );
+ let val = res.unwrap();
+ assert_eq!(val, CKR_FUNCTION_NOT_PARALLEL);
+}
+
+#[test]
+#[serial]
+fn ctx_cancel_function() {
+ let (ctx, sh) = fixture_token().unwrap();
+ let res = ctx.cancel_function(sh);
+ assert!(
+ res.is_ok(),
+ "failed to call C_CancelFunction({}): {}",
+ sh,
+ res.unwrap_err()
+ );
+ let val = res.unwrap();
+ assert_eq!(val, CKR_FUNCTION_NOT_PARALLEL);
+}
+
+#[test]
+#[serial]
+fn ctx_wait_for_slot_event() {
+ let (ctx, _) = fixture_token().unwrap();
+ let res = ctx.wait_for_slot_event(CKF_DONT_BLOCK);
+ if res.is_err() {
+ // SoftHSM does not support this function, so this is what we should compare against
+ //assert_eq!(Error::Pkcs11(CKR_FUNCTION_NOT_SUPPORTED), res.unwrap_err());
+ match res.unwrap_err() {
+ Error::Pkcs11(CKR_FUNCTION_NOT_SUPPORTED) => {
+ println!("as expected SoftHSM does not support this function");
+ }
+ _ => panic!("ahhh"),
+ }
+ } else {
+ assert!(
+ res.is_ok(),
+ "failed to call C_WaitForSlotEvent({}): {}",
+ CKF_DONT_BLOCK,
+ res.unwrap_err()
+ );
+ }
+}
diff --git a/third_party/rust/pkcs11/src/types.rs b/third_party/rust/pkcs11/src/types.rs
new file mode 100644
index 0000000000..9dd1289334
--- /dev/null
+++ b/third_party/rust/pkcs11/src/types.rs
@@ -0,0 +1,2497 @@
+// Copyright 2017 Marcus Heese
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#![allow(non_camel_case_types, non_snake_case)]
+
+// Cryptoki's packed structs interfere with the Clone trait, so we implement Copy and use this
+macro_rules! packed_clone {
+ ($name:ty) => (
+ impl Clone for $name { fn clone(&self) -> $name { *self } }
+ )
+}
+
+// packed structs only needed on Windows, pkcs11.h mentions
+macro_rules! cryptoki_aligned {
+ ($decl:item) => {
+ #[cfg(windows)]
+ #[repr(packed, C)]
+ $decl
+ #[cfg(not(windows))]
+ #[repr(C)]
+ $decl
+ }
+}
+
+use std;
+use std::mem;
+use std::slice;
+use std::ptr;
+use num_bigint::BigUint;
+
+use functions::*;
+use super::CkFrom;
+
+
+pub const CK_TRUE: CK_BBOOL = 1;
+pub const CK_FALSE: CK_BBOOL = 0;
+
+//// an unsigned 8-bit value
+pub type CK_BYTE = u8;
+pub type CK_BYTE_PTR = *mut CK_BYTE;
+
+/// an unsigned 8-bit character
+pub type CK_CHAR = CK_BYTE;
+pub type CK_CHAR_PTR = *mut CK_CHAR;
+
+/// an 8-bit UTF-8 character
+pub type CK_UTF8CHAR = CK_BYTE;
+pub type CK_UTF8CHAR_PTR = *mut CK_UTF8CHAR;
+
+/// a BYTE-sized Boolean flag
+pub type CK_BBOOL = CK_BYTE;
+
+/// an unsigned value, at least 32 bits long
+#[cfg(windows)]
+pub type CK_ULONG = u32;
+#[cfg(not(windows))]
+pub type CK_ULONG = usize;
+pub type CK_ULONG_PTR = *mut CK_ULONG;
+
+/// a signed value, the same size as a CK_ULONG
+#[cfg(windows)]
+pub type CK_LONG = i32;
+#[cfg(not(windows))]
+pub type CK_LONG = isize;
+
+
+/// at least 32 bits; each bit is a Boolean flag
+pub type CK_FLAGS = CK_ULONG;
+
+/* some special values for certain CK_ULONG variables */
+pub const CK_UNAVAILABLE_INFORMATION: CK_ULONG = !0;
+pub const CK_EFFECTIVELY_INFINITE: CK_ULONG = 0;
+
+#[derive(Debug)]
+#[repr(u8)]
+pub enum CK_VOID {
+ #[doc(hidden)] __Variant1,
+ #[doc(hidden)] __Variant2,
+}
+pub type CK_VOID_PTR = *mut CK_VOID;
+
+/// Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void
+pub type CK_VOID_PTR_PTR = *mut CK_VOID_PTR;
+
+/// The following value is always invalid if used as a session
+/// handle or object handle
+pub const CK_INVALID_HANDLE: CK_ULONG = 0;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy, Default)]
+ pub struct CK_VERSION {
+ pub major: CK_BYTE, /* integer portion of version number */
+ pub minor: CK_BYTE, /* 1/100ths portion of version number */
+ }
+}
+packed_clone!(CK_VERSION);
+
+pub type CK_VERSION_PTR = *mut CK_VERSION;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy, Default)]
+ pub struct CK_INFO {
+ /* manufacturerID and libraryDecription have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ pub cryptokiVersion: CK_VERSION, /* Cryptoki interface ver */
+ pub manufacturerID: [CK_UTF8CHAR; 32], /* blank padded */
+ pub flags: CK_FLAGS, /* must be zero */
+ pub libraryDescription: [CK_UTF8CHAR; 32], /* blank padded */
+ pub libraryVersion: CK_VERSION, /* version of library */
+ }
+}
+packed_clone!(CK_INFO);
+
+impl CK_INFO {
+ pub fn new() -> CK_INFO {
+ CK_INFO {
+ cryptokiVersion: Default::default(),
+ manufacturerID: [32; 32],
+ flags: 0,
+ libraryDescription: [32; 32],
+ libraryVersion: Default::default(),
+ }
+ }
+}
+
+pub type CK_INFO_PTR = *mut CK_INFO;
+
+/// CK_NOTIFICATION enumerates the types of notifications that
+/// Cryptoki provides to an application
+pub type CK_NOTIFICATION = CK_ULONG;
+
+pub const CKN_SURRENDER: CK_NOTIFICATION = 0;
+pub const CKN_OTP_CHANGED: CK_NOTIFICATION = 1;
+
+pub type CK_SLOT_ID = CK_ULONG;
+pub type CK_SLOT_ID_PTR = *mut CK_SLOT_ID;
+
+/// CK_SLOT_INFO provides information about a slot
+cryptoki_aligned! {
+ pub struct CK_SLOT_INFO {
+ /// slotDescription and manufacturerID have been changed from
+ /// CK_CHAR to CK_UTF8CHAR for v2.10
+ pub slotDescription: [CK_UTF8CHAR; 64], /* blank padded */
+ pub manufacturerID: [CK_UTF8CHAR; 32], /* blank padded */
+ pub flags: CK_FLAGS,
+
+ /// version of hardware
+ pub hardwareVersion: CK_VERSION, /* version of hardware */
+ /// version of firmware
+ pub firmwareVersion: CK_VERSION, /* version of firmware */
+ }
+}
+
+impl Default for CK_SLOT_INFO {
+ fn default() -> CK_SLOT_INFO {
+ CK_SLOT_INFO {
+ slotDescription: [32; 64],
+ manufacturerID: [32; 32],
+ flags: 0,
+ hardwareVersion: Default::default(),
+ firmwareVersion: Default::default(),
+ }
+ }
+}
+
+impl std::fmt::Debug for CK_SLOT_INFO {
+ fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
+ let sd = self.slotDescription.to_vec();
+ fmt
+ .debug_struct("CK_SLOT_INFO")
+ .field("slotDescription", &sd)
+ .field("manufacturerID", &self.manufacturerID)
+ .field("flags", &self.flags)
+ .field("hardwareVersion", &self.hardwareVersion)
+ .field("firmwareVersion", &self.firmwareVersion)
+ .finish()
+ }
+}
+
+/// a token is there
+pub const CKF_TOKEN_PRESENT: CK_FLAGS = 0x00000001;
+/// removable devices
+pub const CKF_REMOVABLE_DEVICE: CK_FLAGS = 0x00000002;
+/// hardware slot
+pub const CKF_HW_SLOT: CK_FLAGS = 0x00000004;
+
+pub type CK_SLOT_INFO_PTR = *mut CK_SLOT_INFO;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_TOKEN_INFO {
+ /* label, manufacturerID, and model have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ pub label: [CK_UTF8CHAR; 32], /* blank padded */
+ pub manufacturerID: [CK_UTF8CHAR; 32], /* blank padded */
+ pub model: [CK_UTF8CHAR; 16], /* blank padded */
+ pub serialNumber: [CK_CHAR; 16], /* blank padded */
+ pub flags: CK_FLAGS, /* see below */
+ pub ulMaxSessionCount: CK_ULONG, /* max open sessions */
+ pub ulSessionCount: CK_ULONG, /* sess. now open */
+ pub ulMaxRwSessionCount: CK_ULONG, /* max R/W sessions */
+ pub ulRwSessionCount: CK_ULONG, /* R/W sess. now open */
+ pub ulMaxPinLen: CK_ULONG, /* in bytes */
+ pub ulMinPinLen: CK_ULONG, /* in bytes */
+ pub ulTotalPublicMemory: CK_ULONG, /* in bytes */
+ pub ulFreePublicMemory: CK_ULONG, /* in bytes */
+ pub ulTotalPrivateMemory: CK_ULONG, /* in bytes */
+ pub ulFreePrivateMemory: CK_ULONG, /* in bytes */
+ pub hardwareVersion: CK_VERSION, /* version of hardware */
+ pub firmwareVersion: CK_VERSION, /* version of firmware */
+ pub utcTime: [CK_CHAR; 16], /* time */
+ }
+}
+packed_clone!(CK_TOKEN_INFO);
+
+impl Default for CK_TOKEN_INFO {
+ fn default() -> CK_TOKEN_INFO {
+ CK_TOKEN_INFO {
+ label: [32; 32],
+ manufacturerID: [32; 32],
+ model: [32; 16],
+ serialNumber: [32; 16],
+ flags: 0,
+ ulMaxSessionCount: 0,
+ ulSessionCount: 0,
+ ulMaxRwSessionCount: 0,
+ ulRwSessionCount: 0,
+ ulMaxPinLen: 0,
+ ulMinPinLen: 0,
+ ulTotalPublicMemory: 0,
+ ulFreePublicMemory: 0,
+ ulTotalPrivateMemory: 0,
+ ulFreePrivateMemory: 0,
+ hardwareVersion: Default::default(),
+ firmwareVersion: Default::default(),
+ utcTime: [0; 16],
+ }
+ }
+}
+
+/// has random # generator
+pub const CKF_RNG: CK_FLAGS = 0x00000001;
+
+/// token is write-protected
+pub const CKF_WRITE_PROTECTED: CK_FLAGS = 0x00000002;
+
+/// user must login
+pub const CKF_LOGIN_REQUIRED: CK_FLAGS = 0x00000004;
+
+/// normal user's PIN is set
+pub const CKF_USER_PIN_INITIALIZED: CK_FLAGS = 0x00000008;
+
+/// CKF_RESTORE_KEY_NOT_NEEDED. If it is set,
+/// that means that *every* time the state of cryptographic
+/// operations of a session is successfully saved, all keys
+/// needed to continue those operations are stored in the state
+pub const CKF_RESTORE_KEY_NOT_NEEDED: CK_FLAGS = 0x00000020;
+
+/// CKF_CLOCK_ON_TOKEN. If it is set, that means
+/// that the token has some sort of clock. The time on that
+/// clock is returned in the token info structure
+pub const CKF_CLOCK_ON_TOKEN: CK_FLAGS = 0x00000040;
+
+/// CKF_PROTECTED_AUTHENTICATION_PATH. If it is
+/// set, that means that there is some way for the user to login
+/// without sending a PIN through the Cryptoki library itself
+pub const CKF_PROTECTED_AUTHENTICATION_PATH: CK_FLAGS = 0x00000100;
+
+/// CKF_DUAL_CRYPTO_OPERATIONS. If it is true,
+/// that means that a single session with the token can perform
+/// dual simultaneous cryptographic operations (digest and
+/// encrypt; decrypt and digest; sign and encrypt; and decrypt
+/// and sign)
+pub const CKF_DUAL_CRYPTO_OPERATIONS: CK_FLAGS = 0x00000200;
+
+/// CKF_TOKEN_INITIALIZED. If it is true, the
+/// token has been initialized using C_InitializeToken or an
+/// equivalent mechanism outside the scope of PKCS #11.
+/// Calling C_InitializeToken when this flag is set will cause
+/// the token to be reinitialized.
+pub const CKF_TOKEN_INITIALIZED: CK_FLAGS = 0x00000400;
+
+/// CKF_SECONDARY_AUTHENTICATION. If it is
+/// true, the token supports secondary authentication for
+/// private key objects.
+pub const CKF_SECONDARY_AUTHENTICATION: CK_FLAGS = 0x00000800;
+
+/// CKF_USER_PIN_COUNT_LOW. If it is true, an
+/// incorrect user login PIN has been entered at least once
+/// since the last successful authentication.
+pub const CKF_USER_PIN_COUNT_LOW: CK_FLAGS = 0x00010000;
+
+/// CKF_USER_PIN_FINAL_TRY. If it is true,
+/// supplying an incorrect user PIN will it to become locked.
+pub const CKF_USER_PIN_FINAL_TRY: CK_FLAGS = 0x00020000;
+
+/// CKF_USER_PIN_LOCKED. If it is true, the
+/// user PIN has been locked. User login to the token is not
+/// possible.
+pub const CKF_USER_PIN_LOCKED: CK_FLAGS = 0x00040000;
+
+/// CKF_USER_PIN_TO_BE_CHANGED. If it is true,
+/// the user PIN value is the default value set by token
+/// initialization or manufacturing, or the PIN has been
+/// expired by the card.
+pub const CKF_USER_PIN_TO_BE_CHANGED: CK_FLAGS = 0x00080000;
+
+/// CKF_SO_PIN_COUNT_LOW. If it is true, an
+/// incorrect SO login PIN has been entered at least once since
+/// the last successful authentication.
+pub const CKF_SO_PIN_COUNT_LOW: CK_FLAGS = 0x00100000;
+
+/// CKF_SO_PIN_FINAL_TRY. If it is true,
+/// supplying an incorrect SO PIN will it to become locked.
+pub const CKF_SO_PIN_FINAL_TRY: CK_FLAGS = 0x00200000;
+
+/// CKF_SO_PIN_LOCKED. If it is true, the SO
+/// PIN has been locked. SO login to the token is not possible.
+pub const CKF_SO_PIN_LOCKED: CK_FLAGS = 0x00400000;
+
+/// CKF_SO_PIN_TO_BE_CHANGED. If it is true,
+/// the SO PIN value is the default value set by token
+/// initialization or manufacturing, or the PIN has been
+/// expired by the card.
+pub const CKF_SO_PIN_TO_BE_CHANGED: CK_FLAGS = 0x00800000;
+
+pub const CKF_ERROR_STATE: CK_FLAGS = 0x01000000;
+
+pub type CK_TOKEN_INFO_PTR = *mut CK_TOKEN_INFO;
+
+/// CK_SESSION_HANDLE is a Cryptoki-assigned value that
+/// identifies a session
+pub type CK_SESSION_HANDLE = CK_ULONG;
+pub type CK_SESSION_HANDLE_PTR = *mut CK_SESSION_HANDLE;
+
+/// CK_USER_TYPE enumerates the types of Cryptoki users
+pub type CK_USER_TYPE = CK_ULONG;
+
+/// Security Officer
+pub const CKU_SO: CK_USER_TYPE = 0;
+/// Normal user
+pub const CKU_USER: CK_USER_TYPE = 1;
+/// Context specific
+pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2;
+
+/// CK_STATE enumerates the session states
+type CK_STATE = CK_ULONG;
+pub const CKS_RO_PUBLIC_SESSION: CK_STATE = 0;
+pub const CKS_RO_USER_FUNCTIONS: CK_STATE = 1;
+pub const CKS_RW_PUBLIC_SESSION: CK_STATE = 2;
+pub const CKS_RW_USER_FUNCTIONS: CK_STATE = 3;
+pub const CKS_RW_SO_FUNCTIONS: CK_STATE = 4;
+
+cryptoki_aligned! {
+ #[derive(Debug, Default, Copy)]
+ pub struct CK_SESSION_INFO {
+ pub slotID: CK_SLOT_ID,
+ pub state: CK_STATE,
+ pub flags: CK_FLAGS,
+ /// device-dependent error code
+ pub ulDeviceError: CK_ULONG,
+ }
+}
+packed_clone!(CK_SESSION_INFO);
+
+/// session is r/w
+pub const CKF_RW_SESSION: CK_FLAGS = 0x00000002;
+/// no parallel
+pub const CKF_SERIAL_SESSION: CK_FLAGS = 0x00000004;
+
+pub type CK_SESSION_INFO_PTR = *mut CK_SESSION_INFO;
+
+/// CK_OBJECT_HANDLE is a token-specific identifier for an
+/// object
+pub type CK_OBJECT_HANDLE = CK_ULONG;
+pub type CK_OBJECT_HANDLE_PTR = *mut CK_OBJECT_HANDLE;
+
+/// CK_OBJECT_CLASS is a value that identifies the classes (or
+/// types) of objects that Cryptoki recognizes. It is defined
+/// as follows:
+pub type CK_OBJECT_CLASS = CK_ULONG;
+
+/// The following classes of objects are defined:
+pub const CKO_DATA: CK_OBJECT_CLASS = 0x00000000;
+pub const CKO_CERTIFICATE: CK_OBJECT_CLASS = 0x00000001;
+pub const CKO_PUBLIC_KEY: CK_OBJECT_CLASS = 0x00000002;
+pub const CKO_PRIVATE_KEY: CK_OBJECT_CLASS = 0x00000003;
+pub const CKO_SECRET_KEY: CK_OBJECT_CLASS = 0x00000004;
+pub const CKO_HW_FEATURE: CK_OBJECT_CLASS = 0x00000005;
+pub const CKO_DOMAIN_PARAMETERS: CK_OBJECT_CLASS = 0x00000006;
+pub const CKO_MECHANISM: CK_OBJECT_CLASS = 0x00000007;
+pub const CKO_OTP_KEY: CK_OBJECT_CLASS = 0x00000008;
+pub const CKO_VENDOR_DEFINED: CK_OBJECT_CLASS = 0x80000000;
+
+pub type CK_OBJECT_CLASS_PTR = *mut CK_OBJECT_CLASS;
+
+/// CK_HW_FEATURE_TYPE is a value that identifies the hardware feature type
+/// of an object with CK_OBJECT_CLASS equal to CKO_HW_FEATURE.
+pub type CK_HW_FEATURE_TYPE = CK_ULONG;
+
+/// The following hardware feature types are defined
+pub const CKH_MONOTONIC_COUNTER: CK_HW_FEATURE_TYPE = 0x00000001;
+pub const CKH_CLOCK: CK_HW_FEATURE_TYPE = 0x00000002;
+pub const CKH_USER_INTERFACE: CK_HW_FEATURE_TYPE = 0x00000003;
+pub const CKH_VENDOR_DEFINED: CK_HW_FEATURE_TYPE = 0x80000000;
+
+/// CK_KEY_TYPE is a value that identifies a key type
+pub type CK_KEY_TYPE = CK_ULONG;
+
+/// the following key types are defined:
+pub const CKK_RSA: CK_KEY_TYPE = 0x00000000;
+pub const CKK_DSA: CK_KEY_TYPE = 0x00000001;
+pub const CKK_DH: CK_KEY_TYPE = 0x00000002;
+pub const CKK_ECDSA: CK_KEY_TYPE = CKK_EC;
+pub const CKK_EC: CK_KEY_TYPE = 0x00000003;
+pub const CKK_X9_42_DH: CK_KEY_TYPE = 0x00000004;
+pub const CKK_KEA: CK_KEY_TYPE = 0x00000005;
+pub const CKK_GENERIC_SECRET: CK_KEY_TYPE = 0x00000010;
+pub const CKK_RC2: CK_KEY_TYPE = 0x00000011;
+pub const CKK_RC4: CK_KEY_TYPE = 0x00000012;
+pub const CKK_DES: CK_KEY_TYPE = 0x00000013;
+pub const CKK_DES2: CK_KEY_TYPE = 0x00000014;
+pub const CKK_DES3: CK_KEY_TYPE = 0x00000015;
+pub const CKK_CAST: CK_KEY_TYPE = 0x00000016;
+pub const CKK_CAST3: CK_KEY_TYPE = 0x00000017;
+pub const CKK_CAST5: CK_KEY_TYPE = CKK_CAST128;
+pub const CKK_CAST128: CK_KEY_TYPE = 0x00000018;
+pub const CKK_RC5: CK_KEY_TYPE = 0x00000019;
+pub const CKK_IDEA: CK_KEY_TYPE = 0x0000001A;
+pub const CKK_SKIPJACK: CK_KEY_TYPE = 0x0000001B;
+pub const CKK_BATON: CK_KEY_TYPE = 0x0000001C;
+pub const CKK_JUNIPER: CK_KEY_TYPE = 0x0000001D;
+pub const CKK_CDMF: CK_KEY_TYPE = 0x0000001E;
+pub const CKK_AES: CK_KEY_TYPE = 0x0000001F;
+pub const CKK_BLOWFISH: CK_KEY_TYPE = 0x00000020;
+pub const CKK_TWOFISH: CK_KEY_TYPE = 0x00000021;
+pub const CKK_SECURID: CK_KEY_TYPE = 0x00000022;
+pub const CKK_HOTP: CK_KEY_TYPE = 0x00000023;
+pub const CKK_ACTI: CK_KEY_TYPE = 0x00000024;
+pub const CKK_CAMELLIA: CK_KEY_TYPE = 0x00000025;
+pub const CKK_ARIA: CK_KEY_TYPE = 0x00000026;
+pub const CKK_MD5_HMAC: CK_KEY_TYPE = 0x00000027;
+pub const CKK_SHA_1_HMAC: CK_KEY_TYPE = 0x00000028;
+pub const CKK_RIPEMD128_HMAC: CK_KEY_TYPE = 0x00000029;
+pub const CKK_RIPEMD160_HMAC: CK_KEY_TYPE = 0x0000002A;
+pub const CKK_SHA256_HMAC: CK_KEY_TYPE = 0x0000002B;
+pub const CKK_SHA384_HMAC: CK_KEY_TYPE = 0x0000002C;
+pub const CKK_SHA512_HMAC: CK_KEY_TYPE = 0x0000002D;
+pub const CKK_SHA224_HMAC: CK_KEY_TYPE = 0x0000002E;
+pub const CKK_SEED: CK_KEY_TYPE = 0x0000002F;
+pub const CKK_GOSTR3410: CK_KEY_TYPE = 0x00000030;
+pub const CKK_GOSTR3411: CK_KEY_TYPE = 0x00000031;
+pub const CKK_GOST28147: CK_KEY_TYPE = 0x00000032;
+pub const CKK_VENDOR_DEFINED: CK_KEY_TYPE = 0x80000000;
+
+/// CK_CERTIFICATE_TYPE is a value that identifies a certificate
+/// type
+pub type CK_CERTIFICATE_TYPE = CK_ULONG;
+
+pub const CK_CERTIFICATE_CATEGORY_UNSPECIFIED: CK_ULONG = 0;
+pub const CK_CERTIFICATE_CATEGORY_TOKEN_USER: CK_ULONG = 1;
+pub const CK_CERTIFICATE_CATEGORY_AUTHORITY: CK_ULONG = 2;
+pub const CK_CERTIFICATE_CATEGORY_OTHER_ENTITY: CK_ULONG = 3;
+
+pub const CK_SECURITY_DOMAIN_UNSPECIFIED: CK_ULONG = 0;
+pub const CK_SECURITY_DOMAIN_MANUFACTURER: CK_ULONG = 1;
+pub const CK_SECURITY_DOMAIN_OPERATOR: CK_ULONG = 2;
+pub const CK_SECURITY_DOMAIN_THIRD_PARTY: CK_ULONG = 3;
+
+/// The following certificate types are defined:
+pub const CKC_X_509: CK_CERTIFICATE_TYPE = 0x00000000;
+pub const CKC_X_509_ATTR_CERT: CK_CERTIFICATE_TYPE = 0x00000001;
+pub const CKC_WTLS: CK_CERTIFICATE_TYPE = 0x00000002;
+pub const CKC_VENDOR_DEFINED: CK_CERTIFICATE_TYPE = 0x80000000;
+
+/// CK_ATTRIBUTE_TYPE is a value that identifies an attribute
+/// type
+pub type CK_ATTRIBUTE_TYPE = CK_ULONG;
+
+/// The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
+/// consists of an array of values.
+pub const CKF_ARRAY_ATTRIBUTE: CK_FLAGS = 0x40000000;
+
+/// The following OTP-related defines relate to the CKA_OTP_FORMAT attribute
+pub const CK_OTP_FORMAT_DECIMAL: CK_ULONG = 0;
+pub const CK_OTP_FORMAT_HEXADECIMAL: CK_ULONG = 1;
+pub const CK_OTP_FORMAT_ALPHANUMERIC: CK_ULONG = 2;
+pub const CK_OTP_FORMAT_BINARY: CK_ULONG = 3;
+
+/// The following OTP-related defines relate to the CKA_OTP_..._REQUIREMENT
+/// attributes
+pub const CK_OTP_PARAM_IGNORED: CK_ULONG = 0;
+pub const CK_OTP_PARAM_OPTIONAL: CK_ULONG = 1;
+pub const CK_OTP_PARAM_MANDATORY: CK_ULONG = 2;
+
+/// The following attribute types are defined:
+pub const CKA_CLASS: CK_ATTRIBUTE_TYPE = 0x00000000;
+pub const CKA_TOKEN: CK_ATTRIBUTE_TYPE = 0x00000001;
+pub const CKA_PRIVATE: CK_ATTRIBUTE_TYPE = 0x00000002;
+pub const CKA_LABEL: CK_ATTRIBUTE_TYPE = 0x00000003;
+pub const CKA_APPLICATION: CK_ATTRIBUTE_TYPE = 0x00000010;
+pub const CKA_VALUE: CK_ATTRIBUTE_TYPE = 0x00000011;
+pub const CKA_OBJECT_ID: CK_ATTRIBUTE_TYPE = 0x00000012;
+pub const CKA_CERTIFICATE_TYPE: CK_ATTRIBUTE_TYPE = 0x00000080;
+pub const CKA_ISSUER: CK_ATTRIBUTE_TYPE = 0x00000081;
+pub const CKA_SERIAL_NUMBER: CK_ATTRIBUTE_TYPE = 0x00000082;
+pub const CKA_AC_ISSUER: CK_ATTRIBUTE_TYPE = 0x00000083;
+pub const CKA_OWNER: CK_ATTRIBUTE_TYPE = 0x00000084;
+pub const CKA_ATTR_TYPES: CK_ATTRIBUTE_TYPE = 0x00000085;
+pub const CKA_TRUSTED: CK_ATTRIBUTE_TYPE = 0x00000086;
+pub const CKA_CERTIFICATE_CATEGORY: CK_ATTRIBUTE_TYPE = 0x00000087;
+pub const CKA_JAVA_MIDP_SECURITY_DOMAIN: CK_ATTRIBUTE_TYPE = 0x00000088;
+pub const CKA_URL: CK_ATTRIBUTE_TYPE = 0x00000089;
+pub const CKA_HASH_OF_SUBJECT_PUBLIC_KEY: CK_ATTRIBUTE_TYPE = 0x0000008A;
+pub const CKA_HASH_OF_ISSUER_PUBLIC_KEY: CK_ATTRIBUTE_TYPE = 0x0000008B;
+pub const CKA_NAME_HASH_ALGORITHM: CK_ATTRIBUTE_TYPE = 0x0000008C;
+pub const CKA_CHECK_VALUE: CK_ATTRIBUTE_TYPE = 0x00000090;
+
+pub const CKA_KEY_TYPE: CK_ATTRIBUTE_TYPE = 0x00000100;
+pub const CKA_SUBJECT: CK_ATTRIBUTE_TYPE = 0x00000101;
+pub const CKA_ID: CK_ATTRIBUTE_TYPE = 0x00000102;
+pub const CKA_SENSITIVE: CK_ATTRIBUTE_TYPE = 0x00000103;
+pub const CKA_ENCRYPT: CK_ATTRIBUTE_TYPE = 0x00000104;
+pub const CKA_DECRYPT: CK_ATTRIBUTE_TYPE = 0x00000105;
+pub const CKA_WRAP: CK_ATTRIBUTE_TYPE = 0x00000106;
+pub const CKA_UNWRAP: CK_ATTRIBUTE_TYPE = 0x00000107;
+pub const CKA_SIGN: CK_ATTRIBUTE_TYPE = 0x00000108;
+pub const CKA_SIGN_RECOVER: CK_ATTRIBUTE_TYPE = 0x00000109;
+pub const CKA_VERIFY: CK_ATTRIBUTE_TYPE = 0x0000010A;
+pub const CKA_VERIFY_RECOVER: CK_ATTRIBUTE_TYPE = 0x0000010B;
+pub const CKA_DERIVE: CK_ATTRIBUTE_TYPE = 0x0000010C;
+pub const CKA_START_DATE: CK_ATTRIBUTE_TYPE = 0x00000110;
+pub const CKA_END_DATE: CK_ATTRIBUTE_TYPE = 0x00000111;
+pub const CKA_MODULUS: CK_ATTRIBUTE_TYPE = 0x00000120;
+pub const CKA_MODULUS_BITS: CK_ATTRIBUTE_TYPE = 0x00000121;
+pub const CKA_PUBLIC_EXPONENT: CK_ATTRIBUTE_TYPE = 0x00000122;
+pub const CKA_PRIVATE_EXPONENT: CK_ATTRIBUTE_TYPE = 0x00000123;
+pub const CKA_PRIME_1: CK_ATTRIBUTE_TYPE = 0x00000124;
+pub const CKA_PRIME_2: CK_ATTRIBUTE_TYPE = 0x00000125;
+pub const CKA_EXPONENT_1: CK_ATTRIBUTE_TYPE = 0x00000126;
+pub const CKA_EXPONENT_2: CK_ATTRIBUTE_TYPE = 0x00000127;
+pub const CKA_COEFFICIENT: CK_ATTRIBUTE_TYPE = 0x00000128;
+pub const CKA_PUBLIC_KEY_INFO: CK_ATTRIBUTE_TYPE = 0x00000129;
+pub const CKA_PRIME: CK_ATTRIBUTE_TYPE = 0x00000130;
+pub const CKA_SUBPRIME: CK_ATTRIBUTE_TYPE = 0x00000131;
+pub const CKA_BASE: CK_ATTRIBUTE_TYPE = 0x00000132;
+
+pub const CKA_PRIME_BITS: CK_ATTRIBUTE_TYPE = 0x00000133;
+pub const CKA_SUBPRIME_BITS: CK_ATTRIBUTE_TYPE = 0x00000134;
+pub const CKA_SUB_PRIME_BITS: CK_ATTRIBUTE_TYPE = CKA_SUBPRIME_BITS;
+
+pub const CKA_VALUE_BITS: CK_ATTRIBUTE_TYPE = 0x00000160;
+pub const CKA_VALUE_LEN: CK_ATTRIBUTE_TYPE = 0x00000161;
+pub const CKA_EXTRACTABLE: CK_ATTRIBUTE_TYPE = 0x00000162;
+pub const CKA_LOCAL: CK_ATTRIBUTE_TYPE = 0x00000163;
+pub const CKA_NEVER_EXTRACTABLE: CK_ATTRIBUTE_TYPE = 0x00000164;
+pub const CKA_ALWAYS_SENSITIVE: CK_ATTRIBUTE_TYPE = 0x00000165;
+pub const CKA_KEY_GEN_MECHANISM: CK_ATTRIBUTE_TYPE = 0x00000166;
+
+pub const CKA_MODIFIABLE: CK_ATTRIBUTE_TYPE = 0x00000170;
+pub const CKA_COPYABLE: CK_ATTRIBUTE_TYPE = 0x00000171;
+
+pub const CKA_DESTROYABLE: CK_ATTRIBUTE_TYPE = 0x00000172;
+
+pub const CKA_ECDSA_PARAMS: CK_ATTRIBUTE_TYPE = CKA_EC_PARAMS;
+pub const CKA_EC_PARAMS: CK_ATTRIBUTE_TYPE = 0x00000180;
+
+pub const CKA_EC_POINT: CK_ATTRIBUTE_TYPE = 0x00000181;
+
+pub const CKA_SECONDARY_AUTH: CK_ATTRIBUTE_TYPE = 0x00000200; /* Deprecated */
+pub const CKA_AUTH_PIN_FLAGS: CK_ATTRIBUTE_TYPE = 0x00000201; /* Deprecated */
+
+pub const CKA_ALWAYS_AUTHENTICATE: CK_ATTRIBUTE_TYPE = 0x00000202;
+
+pub const CKA_WRAP_WITH_TRUSTED: CK_ATTRIBUTE_TYPE = 0x00000210;
+pub const CKA_WRAP_TEMPLATE: CK_ATTRIBUTE_TYPE = (CKF_ARRAY_ATTRIBUTE | 0x00000211);
+pub const CKA_UNWRAP_TEMPLATE: CK_ATTRIBUTE_TYPE = (CKF_ARRAY_ATTRIBUTE | 0x00000212);
+pub const CKA_DERIVE_TEMPLATE: CK_ATTRIBUTE_TYPE = (CKF_ARRAY_ATTRIBUTE | 0x00000213);
+
+pub const CKA_OTP_FORMAT: CK_ATTRIBUTE_TYPE = 0x00000220;
+pub const CKA_OTP_LENGTH: CK_ATTRIBUTE_TYPE = 0x00000221;
+pub const CKA_OTP_TIME_INTERVAL: CK_ATTRIBUTE_TYPE = 0x00000222;
+pub const CKA_OTP_USER_FRIENDLY_MODE: CK_ATTRIBUTE_TYPE = 0x00000223;
+pub const CKA_OTP_CHALLENGE_REQUIREMENT: CK_ATTRIBUTE_TYPE = 0x00000224;
+pub const CKA_OTP_TIME_REQUIREMENT: CK_ATTRIBUTE_TYPE = 0x00000225;
+pub const CKA_OTP_COUNTER_REQUIREMENT: CK_ATTRIBUTE_TYPE = 0x00000226;
+pub const CKA_OTP_PIN_REQUIREMENT: CK_ATTRIBUTE_TYPE = 0x00000227;
+pub const CKA_OTP_COUNTER: CK_ATTRIBUTE_TYPE = 0x0000022E;
+pub const CKA_OTP_TIME: CK_ATTRIBUTE_TYPE = 0x0000022F;
+pub const CKA_OTP_USER_IDENTIFIER: CK_ATTRIBUTE_TYPE = 0x0000022A;
+pub const CKA_OTP_SERVICE_IDENTIFIER: CK_ATTRIBUTE_TYPE = 0x0000022B;
+pub const CKA_OTP_SERVICE_LOGO: CK_ATTRIBUTE_TYPE = 0x0000022C;
+pub const CKA_OTP_SERVICE_LOGO_TYPE: CK_ATTRIBUTE_TYPE = 0x0000022D;
+
+pub const CKA_GOSTR3410_PARAMS: CK_ATTRIBUTE_TYPE = 0x00000250;
+pub const CKA_GOSTR3411_PARAMS: CK_ATTRIBUTE_TYPE = 0x00000251;
+pub const CKA_GOST28147_PARAMS: CK_ATTRIBUTE_TYPE = 0x00000252;
+
+pub const CKA_HW_FEATURE_TYPE: CK_ATTRIBUTE_TYPE = 0x00000300;
+pub const CKA_RESET_ON_INIT: CK_ATTRIBUTE_TYPE = 0x00000301;
+pub const CKA_HAS_RESET: CK_ATTRIBUTE_TYPE = 0x00000302;
+
+pub const CKA_PIXEL_X: CK_ATTRIBUTE_TYPE = 0x00000400;
+pub const CKA_PIXEL_Y: CK_ATTRIBUTE_TYPE = 0x00000401;
+pub const CKA_RESOLUTION: CK_ATTRIBUTE_TYPE = 0x00000402;
+pub const CKA_CHAR_ROWS: CK_ATTRIBUTE_TYPE = 0x00000403;
+pub const CKA_CHAR_COLUMNS: CK_ATTRIBUTE_TYPE = 0x00000404;
+pub const CKA_COLOR: CK_ATTRIBUTE_TYPE = 0x00000405;
+pub const CKA_BITS_PER_PIXEL: CK_ATTRIBUTE_TYPE = 0x00000406;
+pub const CKA_CHAR_SETS: CK_ATTRIBUTE_TYPE = 0x00000480;
+pub const CKA_ENCODING_METHODS: CK_ATTRIBUTE_TYPE = 0x00000481;
+pub const CKA_MIME_TYPES: CK_ATTRIBUTE_TYPE = 0x00000482;
+pub const CKA_MECHANISM_TYPE: CK_ATTRIBUTE_TYPE = 0x00000500;
+pub const CKA_REQUIRED_CMS_ATTRIBUTES: CK_ATTRIBUTE_TYPE = 0x00000501;
+pub const CKA_DEFAULT_CMS_ATTRIBUTES: CK_ATTRIBUTE_TYPE = 0x00000502;
+pub const CKA_SUPPORTED_CMS_ATTRIBUTES: CK_ATTRIBUTE_TYPE = 0x00000503;
+pub const CKA_ALLOWED_MECHANISMS: CK_ATTRIBUTE_TYPE = (CKF_ARRAY_ATTRIBUTE | 0x00000600);
+
+pub const CKA_VENDOR_DEFINED: CK_ATTRIBUTE_TYPE = 0x80000000;
+
+/// CK_ATTRIBUTE is a structure that includes the type, length
+/// and value of an attribute
+cryptoki_aligned! {
+ #[derive(Copy)]
+ pub struct CK_ATTRIBUTE {
+ pub attrType: CK_ATTRIBUTE_TYPE,
+ pub pValue: CK_VOID_PTR,
+ /// in bytes
+ pub ulValueLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_ATTRIBUTE);
+
+pub type CK_ATTRIBUTE_PTR = *mut CK_ATTRIBUTE;
+
+impl Default for CK_ATTRIBUTE {
+ fn default() -> Self {
+ Self {
+ attrType: CKA_VENDOR_DEFINED,
+ pValue: ptr::null_mut(),
+ ulValueLen: 0,
+ }
+ }
+}
+
+impl std::fmt::Debug for CK_ATTRIBUTE {
+ fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
+ let attrType = format!("0x{:x}", self.attrType);
+ let data = unsafe { slice::from_raw_parts(self.pValue as *const u8, self.ulValueLen as usize) };
+ fmt
+ .debug_struct("CK_ATTRIBUTE")
+ .field("attrType", &attrType)
+ .field("pValue", &data)
+ .field("ulValueLen", &self.ulValueLen)
+ .finish()
+ }
+}
+
+impl CK_ATTRIBUTE {
+ pub fn new(attrType: CK_ATTRIBUTE_TYPE) -> Self {
+ Self {
+ attrType: attrType,
+ pValue: ptr::null_mut(),
+ ulValueLen: 0,
+ }
+ }
+
+ pub fn with_bool(mut self, b: &CK_BBOOL) -> Self {
+ self.pValue = b as *const CK_BBOOL as CK_VOID_PTR;
+ self.ulValueLen = 1;
+ self
+ }
+
+ pub fn set_bool(&mut self, b: &CK_BBOOL) {
+ self.pValue = b as *const CK_BBOOL as CK_VOID_PTR;
+ if self.ulValueLen == 0 {
+ self.ulValueLen = 1;
+ }
+ }
+
+ pub fn get_bool(&self) -> bool {
+ let data: CK_BBOOL = unsafe { mem::transmute_copy(&*self.pValue) };
+ CkFrom::from(data)
+ }
+
+ pub fn with_ck_ulong(mut self, val: &CK_ULONG) -> Self {
+ self.pValue = val as *const _ as CK_VOID_PTR;
+ self.ulValueLen = std::mem::size_of::<CK_ULONG>() as CK_ULONG;
+ self
+ }
+
+ pub fn set_ck_ulong(&mut self, val: &CK_ULONG) {
+ self.pValue = val as *const _ as CK_VOID_PTR;
+ if self.ulValueLen == 0 {
+ self.ulValueLen = std::mem::size_of::<CK_ULONG>() as CK_ULONG;
+ }
+ }
+
+ pub fn get_ck_ulong(&self) -> CK_ULONG {
+ unsafe { mem::transmute_copy(&*self.pValue) }
+ }
+
+ pub fn with_ck_long(mut self, val: &CK_LONG) -> Self {
+ self.pValue = val as *const _ as CK_VOID_PTR;
+ self.ulValueLen = std::mem::size_of::<CK_LONG>() as CK_ULONG;
+ self
+ }
+
+ pub fn set_ck_long(&mut self, val: &CK_LONG) {
+ self.pValue = val as *const _ as CK_VOID_PTR;
+ if self.ulValueLen == 0 {
+ self.ulValueLen = std::mem::size_of::<CK_LONG>() as CK_ULONG;
+ }
+ }
+
+ pub fn get_ck_long(&self) -> CK_LONG {
+ unsafe { mem::transmute_copy(&*self.pValue) }
+ }
+
+ pub fn with_biginteger(mut self, val: &Vec<u8>) -> Self {
+ self.pValue = val.as_slice().as_ptr() as CK_VOID_PTR;
+ self.ulValueLen = val.len() as CK_ULONG;
+ self
+ }
+
+ pub fn set_biginteger(&mut self, val: &Vec<u8>) {
+ self.pValue = val.as_slice().as_ptr() as CK_VOID_PTR;
+ if self.ulValueLen == 0 {
+ self.ulValueLen = val.len() as CK_ULONG;
+ }
+ }
+
+ pub fn get_biginteger(&self) -> BigUint {
+ let slice = unsafe { slice::from_raw_parts(self.pValue as CK_BYTE_PTR, self.ulValueLen as usize) };
+ BigUint::from_bytes_le(slice)
+ }
+
+ pub fn with_bytes(mut self, val: &[CK_BYTE]) -> Self {
+ self.pValue = val.as_ptr() as CK_VOID_PTR;
+ self.ulValueLen = val.len() as CK_ULONG;
+ self
+ }
+
+ pub fn set_bytes(&mut self, val: &[CK_BYTE]) {
+ self.pValue = val.as_ptr() as CK_VOID_PTR;
+ if self.ulValueLen == 0 {
+ self.ulValueLen = val.len() as CK_ULONG;
+ }
+ }
+
+ pub fn get_bytes(&self) -> Vec<CK_BYTE> {
+ let slice = unsafe { slice::from_raw_parts(self.pValue as CK_BYTE_PTR, self.ulValueLen as usize) };
+ Vec::from(slice).clone()
+ }
+
+ pub fn with_string(mut self, str: &String) -> Self {
+ self.pValue = str.as_ptr() as CK_VOID_PTR;
+ self.ulValueLen = str.len() as CK_ULONG;
+ self
+ }
+
+ pub fn set_string(&mut self, str: &String) {
+ self.pValue = str.as_ptr() as CK_VOID_PTR;
+ if self.ulValueLen == 0 {
+ self.ulValueLen = str.len() as CK_ULONG;
+ }
+ }
+
+ pub fn get_string(&self) -> String {
+ let slice = unsafe { slice::from_raw_parts(self.pValue as CK_BYTE_PTR, self.ulValueLen as usize) };
+ String::from_utf8_lossy(slice).into_owned().clone()
+ }
+
+ pub fn with_date(mut self, date: &CK_DATE) -> Self {
+ self.pValue = (date as *const CK_DATE) as CK_VOID_PTR;
+ self.ulValueLen = mem::size_of::<CK_DATE>() as CK_ULONG;
+ self
+ }
+
+ pub fn set_date(&mut self, date: &CK_DATE) {
+ self.pValue = (date as *const CK_DATE) as CK_VOID_PTR;
+ if self.ulValueLen == 0 {
+ self.ulValueLen = mem::size_of::<CK_DATE>() as CK_ULONG;
+ }
+ }
+
+ pub fn get_date(&self) -> CK_DATE {
+ unsafe { mem::transmute_copy(&*self.pValue) }
+ }
+
+ // this works for C structs and primitives, but not for vectors, slices, strings
+ //pub fn set_ptr<T>(&mut self, val: &T) {
+ // self.pValue = (val as *const T) as CK_VOID_PTR;
+ //}
+}
+
+//trait CkAttributeFrom<T> {
+// fn from_ck(T, CK_ATTRIBUTE_TYPE) -> Self;
+//}
+//
+//trait CkAttributeInto<T> {
+// fn into_attribute(self, CK_ATTRIBUTE_TYPE) -> CK_ATTRIBUTE;
+//}
+//
+//impl<T> CkAttributeInto<T> for T where CK_ATTRIBUTE: CkAttributeFrom<T> {
+// fn into_attribute(self, attrType: CK_ATTRIBUTE_TYPE) -> CK_ATTRIBUTE {
+// CkAttributeFrom::from_ck(self, attrType)
+// }
+//}
+//
+//impl CkAttributeFrom<bool> for CK_ATTRIBUTE {
+// fn from_ck(b: bool, attrType: CK_ATTRIBUTE_TYPE) -> CK_ATTRIBUTE {
+// let val: CK_BBOOL = if b { 1 } else { 0 };
+// let ret = Self {
+// attrType: attrType,
+// pValue: &val as *const u8 as *const CK_VOID,
+// ulValueLen: 1,
+// };
+// println!("{:?}", ret);
+// ret
+// }
+//}
+
+/// CK_DATE is a structure that defines a date
+cryptoki_aligned! {
+ #[derive(Debug, Default, Copy)]
+ pub struct CK_DATE {
+ /// the year ("1900" - "9999")
+ pub year: [CK_CHAR; 4],
+ /// the month ("01" - "12")
+ pub month: [CK_CHAR; 2],
+ /// the day ("01" - "31")
+ pub day: [CK_CHAR; 2],
+ }
+}
+packed_clone!(CK_DATE);
+
+/// CK_MECHANISM_TYPE is a value that identifies a mechanism
+/// type
+pub type CK_MECHANISM_TYPE = CK_ULONG;
+
+/// the following mechanism types are defined:
+pub const CKM_RSA_PKCS_KEY_PAIR_GEN: CK_MECHANISM_TYPE = 0x00000000;
+pub const CKM_RSA_PKCS: CK_MECHANISM_TYPE = 0x00000001;
+pub const CKM_RSA_9796: CK_MECHANISM_TYPE = 0x00000002;
+pub const CKM_RSA_X_509: CK_MECHANISM_TYPE = 0x00000003;
+
+pub const CKM_MD2_RSA_PKCS: CK_MECHANISM_TYPE = 0x00000004;
+pub const CKM_MD5_RSA_PKCS: CK_MECHANISM_TYPE = 0x00000005;
+pub const CKM_SHA1_RSA_PKCS: CK_MECHANISM_TYPE = 0x00000006;
+
+pub const CKM_RIPEMD128_RSA_PKCS: CK_MECHANISM_TYPE = 0x00000007;
+pub const CKM_RIPEMD160_RSA_PKCS: CK_MECHANISM_TYPE = 0x00000008;
+pub const CKM_RSA_PKCS_OAEP: CK_MECHANISM_TYPE = 0x00000009;
+
+pub const CKM_RSA_X9_31_KEY_PAIR_GEN: CK_MECHANISM_TYPE = 0x0000000A;
+pub const CKM_RSA_X9_31: CK_MECHANISM_TYPE = 0x0000000B;
+pub const CKM_SHA1_RSA_X9_31: CK_MECHANISM_TYPE = 0x0000000C;
+pub const CKM_RSA_PKCS_PSS: CK_MECHANISM_TYPE = 0x0000000D;
+pub const CKM_SHA1_RSA_PKCS_PSS: CK_MECHANISM_TYPE = 0x0000000E;
+
+pub const CKM_DSA_KEY_PAIR_GEN: CK_MECHANISM_TYPE = 0x00000010;
+pub const CKM_DSA: CK_MECHANISM_TYPE = 0x00000011;
+pub const CKM_DSA_SHA1: CK_MECHANISM_TYPE = 0x00000012;
+pub const CKM_DSA_SHA224: CK_MECHANISM_TYPE = 0x00000013;
+pub const CKM_DSA_SHA256: CK_MECHANISM_TYPE = 0x00000014;
+pub const CKM_DSA_SHA384: CK_MECHANISM_TYPE = 0x00000015;
+pub const CKM_DSA_SHA512: CK_MECHANISM_TYPE = 0x00000016;
+
+pub const CKM_DH_PKCS_KEY_PAIR_GEN: CK_MECHANISM_TYPE = 0x00000020;
+pub const CKM_DH_PKCS_DERIVE: CK_MECHANISM_TYPE = 0x00000021;
+
+pub const CKM_X9_42_DH_KEY_PAIR_GEN: CK_MECHANISM_TYPE = 0x00000030;
+pub const CKM_X9_42_DH_DERIVE: CK_MECHANISM_TYPE = 0x00000031;
+pub const CKM_X9_42_DH_HYBRID_DERIVE: CK_MECHANISM_TYPE = 0x00000032;
+pub const CKM_X9_42_MQV_DERIVE: CK_MECHANISM_TYPE = 0x00000033;
+
+pub const CKM_SHA256_RSA_PKCS: CK_MECHANISM_TYPE = 0x00000040;
+pub const CKM_SHA384_RSA_PKCS: CK_MECHANISM_TYPE = 0x00000041;
+pub const CKM_SHA512_RSA_PKCS: CK_MECHANISM_TYPE = 0x00000042;
+pub const CKM_SHA256_RSA_PKCS_PSS: CK_MECHANISM_TYPE = 0x00000043;
+pub const CKM_SHA384_RSA_PKCS_PSS: CK_MECHANISM_TYPE = 0x00000044;
+pub const CKM_SHA512_RSA_PKCS_PSS: CK_MECHANISM_TYPE = 0x00000045;
+
+pub const CKM_SHA224_RSA_PKCS: CK_MECHANISM_TYPE = 0x00000046;
+pub const CKM_SHA224_RSA_PKCS_PSS: CK_MECHANISM_TYPE = 0x00000047;
+
+pub const CKM_SHA512_224: CK_MECHANISM_TYPE = 0x00000048;
+pub const CKM_SHA512_224_HMAC: CK_MECHANISM_TYPE = 0x00000049;
+pub const CKM_SHA512_224_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x0000004A;
+pub const CKM_SHA512_224_KEY_DERIVATION: CK_MECHANISM_TYPE = 0x0000004B;
+pub const CKM_SHA512_256: CK_MECHANISM_TYPE = 0x0000004C;
+pub const CKM_SHA512_256_HMAC: CK_MECHANISM_TYPE = 0x0000004D;
+pub const CKM_SHA512_256_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x0000004E;
+pub const CKM_SHA512_256_KEY_DERIVATION: CK_MECHANISM_TYPE = 0x0000004F;
+
+pub const CKM_SHA512_T: CK_MECHANISM_TYPE = 0x00000050;
+pub const CKM_SHA512_T_HMAC: CK_MECHANISM_TYPE = 0x00000051;
+pub const CKM_SHA512_T_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000052;
+pub const CKM_SHA512_T_KEY_DERIVATION: CK_MECHANISM_TYPE = 0x00000053;
+
+pub const CKM_RC2_KEY_GEN: CK_MECHANISM_TYPE = 0x00000100;
+pub const CKM_RC2_ECB: CK_MECHANISM_TYPE = 0x00000101;
+pub const CKM_RC2_CBC: CK_MECHANISM_TYPE = 0x00000102;
+pub const CKM_RC2_MAC: CK_MECHANISM_TYPE = 0x00000103;
+
+pub const CKM_RC2_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000104;
+pub const CKM_RC2_CBC_PAD: CK_MECHANISM_TYPE = 0x00000105;
+
+pub const CKM_RC4_KEY_GEN: CK_MECHANISM_TYPE = 0x00000110;
+pub const CKM_RC4: CK_MECHANISM_TYPE = 0x00000111;
+pub const CKM_DES_KEY_GEN: CK_MECHANISM_TYPE = 0x00000120;
+pub const CKM_DES_ECB: CK_MECHANISM_TYPE = 0x00000121;
+pub const CKM_DES_CBC: CK_MECHANISM_TYPE = 0x00000122;
+pub const CKM_DES_MAC: CK_MECHANISM_TYPE = 0x00000123;
+
+pub const CKM_DES_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000124;
+pub const CKM_DES_CBC_PAD: CK_MECHANISM_TYPE = 0x00000125;
+
+pub const CKM_DES2_KEY_GEN: CK_MECHANISM_TYPE = 0x00000130;
+pub const CKM_DES3_KEY_GEN: CK_MECHANISM_TYPE = 0x00000131;
+pub const CKM_DES3_ECB: CK_MECHANISM_TYPE = 0x00000132;
+pub const CKM_DES3_CBC: CK_MECHANISM_TYPE = 0x00000133;
+pub const CKM_DES3_MAC: CK_MECHANISM_TYPE = 0x00000134;
+
+pub const CKM_DES3_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000135;
+pub const CKM_DES3_CBC_PAD: CK_MECHANISM_TYPE = 0x00000136;
+pub const CKM_DES3_CMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000137;
+pub const CKM_DES3_CMAC: CK_MECHANISM_TYPE = 0x00000138;
+pub const CKM_CDMF_KEY_GEN: CK_MECHANISM_TYPE = 0x00000140;
+pub const CKM_CDMF_ECB: CK_MECHANISM_TYPE = 0x00000141;
+pub const CKM_CDMF_CBC: CK_MECHANISM_TYPE = 0x00000142;
+pub const CKM_CDMF_MAC: CK_MECHANISM_TYPE = 0x00000143;
+pub const CKM_CDMF_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000144;
+pub const CKM_CDMF_CBC_PAD: CK_MECHANISM_TYPE = 0x00000145;
+
+pub const CKM_DES_OFB64: CK_MECHANISM_TYPE = 0x00000150;
+pub const CKM_DES_OFB8: CK_MECHANISM_TYPE = 0x00000151;
+pub const CKM_DES_CFB64: CK_MECHANISM_TYPE = 0x00000152;
+pub const CKM_DES_CFB8: CK_MECHANISM_TYPE = 0x00000153;
+
+pub const CKM_MD2: CK_MECHANISM_TYPE = 0x00000200;
+
+pub const CKM_MD2_HMAC: CK_MECHANISM_TYPE = 0x00000201;
+pub const CKM_MD2_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000202;
+
+pub const CKM_MD5: CK_MECHANISM_TYPE = 0x00000210;
+
+pub const CKM_MD5_HMAC: CK_MECHANISM_TYPE = 0x00000211;
+pub const CKM_MD5_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000212;
+
+pub const CKM_SHA_1: CK_MECHANISM_TYPE = 0x00000220;
+
+pub const CKM_SHA_1_HMAC: CK_MECHANISM_TYPE = 0x00000221;
+pub const CKM_SHA_1_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000222;
+
+pub const CKM_RIPEMD128: CK_MECHANISM_TYPE = 0x00000230;
+pub const CKM_RIPEMD128_HMAC: CK_MECHANISM_TYPE = 0x00000231;
+pub const CKM_RIPEMD128_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000232;
+pub const CKM_RIPEMD160: CK_MECHANISM_TYPE = 0x00000240;
+pub const CKM_RIPEMD160_HMAC: CK_MECHANISM_TYPE = 0x00000241;
+pub const CKM_RIPEMD160_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000242;
+
+pub const CKM_SHA256: CK_MECHANISM_TYPE = 0x00000250;
+pub const CKM_SHA256_HMAC: CK_MECHANISM_TYPE = 0x00000251;
+pub const CKM_SHA256_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000252;
+pub const CKM_SHA224: CK_MECHANISM_TYPE = 0x00000255;
+pub const CKM_SHA224_HMAC: CK_MECHANISM_TYPE = 0x00000256;
+pub const CKM_SHA224_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000257;
+pub const CKM_SHA384: CK_MECHANISM_TYPE = 0x00000260;
+pub const CKM_SHA384_HMAC: CK_MECHANISM_TYPE = 0x00000261;
+pub const CKM_SHA384_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000262;
+pub const CKM_SHA512: CK_MECHANISM_TYPE = 0x00000270;
+pub const CKM_SHA512_HMAC: CK_MECHANISM_TYPE = 0x00000271;
+pub const CKM_SHA512_HMAC_GENERAL: CK_MECHANISM_TYPE = 0x00000272;
+pub const CKM_SECURID_KEY_GEN: CK_MECHANISM_TYPE = 0x00000280;
+pub const CKM_SECURID: CK_MECHANISM_TYPE = 0x00000282;
+pub const CKM_HOTP_KEY_GEN: CK_MECHANISM_TYPE = 0x00000290;
+pub const CKM_HOTP: CK_MECHANISM_TYPE = 0x00000291;
+pub const CKM_ACTI: CK_MECHANISM_TYPE = 0x000002A0;
+pub const CKM_ACTI_KEY_GEN: CK_MECHANISM_TYPE = 0x000002A1;
+
+pub const CKM_CAST_KEY_GEN: CK_MECHANISM_TYPE = 0x00000300;
+pub const CKM_CAST_ECB: CK_MECHANISM_TYPE = 0x00000301;
+pub const CKM_CAST_CBC: CK_MECHANISM_TYPE = 0x00000302;
+pub const CKM_CAST_MAC: CK_MECHANISM_TYPE = 0x00000303;
+pub const CKM_CAST_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000304;
+pub const CKM_CAST_CBC_PAD: CK_MECHANISM_TYPE = 0x00000305;
+pub const CKM_CAST3_KEY_GEN: CK_MECHANISM_TYPE = 0x00000310;
+pub const CKM_CAST3_ECB: CK_MECHANISM_TYPE = 0x00000311;
+pub const CKM_CAST3_CBC: CK_MECHANISM_TYPE = 0x00000312;
+pub const CKM_CAST3_MAC: CK_MECHANISM_TYPE = 0x00000313;
+pub const CKM_CAST3_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000314;
+pub const CKM_CAST3_CBC_PAD: CK_MECHANISM_TYPE = 0x00000315;
+/// Note that CAST128 and CAST5 are the same algorithm
+pub const CKM_CAST5_KEY_GEN: CK_MECHANISM_TYPE = 0x00000320;
+pub const CKM_CAST128_KEY_GEN: CK_MECHANISM_TYPE = 0x00000320;
+pub const CKM_CAST5_ECB: CK_MECHANISM_TYPE = 0x00000321;
+pub const CKM_CAST128_ECB: CK_MECHANISM_TYPE = 0x00000321;
+pub const CKM_CAST5_CBC: CK_MECHANISM_TYPE = CKM_CAST128_CBC;
+pub const CKM_CAST128_CBC: CK_MECHANISM_TYPE = 0x00000322;
+pub const CKM_CAST5_MAC: CK_MECHANISM_TYPE = CKM_CAST128_MAC;
+pub const CKM_CAST128_MAC: CK_MECHANISM_TYPE = 0x00000323;
+pub const CKM_CAST5_MAC_GENERAL: CK_MECHANISM_TYPE = CKM_CAST128_MAC_GENERAL;
+pub const CKM_CAST128_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000324;
+pub const CKM_CAST5_CBC_PAD: CK_MECHANISM_TYPE = CKM_CAST128_CBC_PAD;
+pub const CKM_CAST128_CBC_PAD: CK_MECHANISM_TYPE = 0x00000325;
+pub const CKM_RC5_KEY_GEN: CK_MECHANISM_TYPE = 0x00000330;
+pub const CKM_RC5_ECB: CK_MECHANISM_TYPE = 0x00000331;
+pub const CKM_RC5_CBC: CK_MECHANISM_TYPE = 0x00000332;
+pub const CKM_RC5_MAC: CK_MECHANISM_TYPE = 0x00000333;
+pub const CKM_RC5_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000334;
+pub const CKM_RC5_CBC_PAD: CK_MECHANISM_TYPE = 0x00000335;
+pub const CKM_IDEA_KEY_GEN: CK_MECHANISM_TYPE = 0x00000340;
+pub const CKM_IDEA_ECB: CK_MECHANISM_TYPE = 0x00000341;
+pub const CKM_IDEA_CBC: CK_MECHANISM_TYPE = 0x00000342;
+pub const CKM_IDEA_MAC: CK_MECHANISM_TYPE = 0x00000343;
+pub const CKM_IDEA_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000344;
+pub const CKM_IDEA_CBC_PAD: CK_MECHANISM_TYPE = 0x00000345;
+pub const CKM_GENERIC_SECRET_KEY_GEN: CK_MECHANISM_TYPE = 0x00000350;
+pub const CKM_CONCATENATE_BASE_AND_KEY: CK_MECHANISM_TYPE = 0x00000360;
+pub const CKM_CONCATENATE_BASE_AND_DATA: CK_MECHANISM_TYPE = 0x00000362;
+pub const CKM_CONCATENATE_DATA_AND_BASE: CK_MECHANISM_TYPE = 0x00000363;
+pub const CKM_XOR_BASE_AND_DATA: CK_MECHANISM_TYPE = 0x00000364;
+pub const CKM_EXTRACT_KEY_FROM_KEY: CK_MECHANISM_TYPE = 0x00000365;
+pub const CKM_SSL3_PRE_MASTER_KEY_GEN: CK_MECHANISM_TYPE = 0x00000370;
+pub const CKM_SSL3_MASTER_KEY_DERIVE: CK_MECHANISM_TYPE = 0x00000371;
+pub const CKM_SSL3_KEY_AND_MAC_DERIVE: CK_MECHANISM_TYPE = 0x00000372;
+
+pub const CKM_SSL3_MASTER_KEY_DERIVE_DH: CK_MECHANISM_TYPE = 0x00000373;
+pub const CKM_TLS_PRE_MASTER_KEY_GEN: CK_MECHANISM_TYPE = 0x00000374;
+pub const CKM_TLS_MASTER_KEY_DERIVE: CK_MECHANISM_TYPE = 0x00000375;
+pub const CKM_TLS_KEY_AND_MAC_DERIVE: CK_MECHANISM_TYPE = 0x00000376;
+pub const CKM_TLS_MASTER_KEY_DERIVE_DH: CK_MECHANISM_TYPE = 0x00000377;
+
+pub const CKM_TLS_PRF: CK_MECHANISM_TYPE = 0x00000378;
+
+pub const CKM_SSL3_MD5_MAC: CK_MECHANISM_TYPE = 0x00000380;
+pub const CKM_SSL3_SHA1_MAC: CK_MECHANISM_TYPE = 0x00000381;
+pub const CKM_MD5_KEY_DERIVATION: CK_MECHANISM_TYPE = 0x00000390;
+pub const CKM_MD2_KEY_DERIVATION: CK_MECHANISM_TYPE = 0x00000391;
+pub const CKM_SHA1_KEY_DERIVATION: CK_MECHANISM_TYPE = 0x00000392;
+
+pub const CKM_SHA256_KEY_DERIVATION: CK_MECHANISM_TYPE = 0x00000393;
+pub const CKM_SHA384_KEY_DERIVATION: CK_MECHANISM_TYPE = 0x00000394;
+pub const CKM_SHA512_KEY_DERIVATION: CK_MECHANISM_TYPE = 0x00000395;
+pub const CKM_SHA224_KEY_DERIVATION: CK_MECHANISM_TYPE = 0x00000396;
+
+pub const CKM_PBE_MD2_DES_CBC: CK_MECHANISM_TYPE = 0x000003A0;
+pub const CKM_PBE_MD5_DES_CBC: CK_MECHANISM_TYPE = 0x000003A1;
+pub const CKM_PBE_MD5_CAST_CBC: CK_MECHANISM_TYPE = 0x000003A2;
+pub const CKM_PBE_MD5_CAST3_CBC: CK_MECHANISM_TYPE = 0x000003A3;
+pub const CKM_PBE_MD5_CAST5_CBC: CK_MECHANISM_TYPE = CKM_PBE_MD5_CAST128_CBC;
+pub const CKM_PBE_MD5_CAST128_CBC: CK_MECHANISM_TYPE = 0x000003A4;
+pub const CKM_PBE_SHA1_CAST5_CBC: CK_MECHANISM_TYPE = CKM_PBE_SHA1_CAST128_CBC;
+pub const CKM_PBE_SHA1_CAST128_CBC: CK_MECHANISM_TYPE = 0x000003A5;
+pub const CKM_PBE_SHA1_RC4_128: CK_MECHANISM_TYPE = 0x000003A6;
+pub const CKM_PBE_SHA1_RC4_40: CK_MECHANISM_TYPE = 0x000003A7;
+pub const CKM_PBE_SHA1_DES3_EDE_CBC: CK_MECHANISM_TYPE = 0x000003A8;
+pub const CKM_PBE_SHA1_DES2_EDE_CBC: CK_MECHANISM_TYPE = 0x000003A9;
+pub const CKM_PBE_SHA1_RC2_128_CBC: CK_MECHANISM_TYPE = 0x000003AA;
+pub const CKM_PBE_SHA1_RC2_40_CBC: CK_MECHANISM_TYPE = 0x000003AB;
+
+pub const CKM_PKCS5_PBKD2: CK_MECHANISM_TYPE = 0x000003B0;
+
+pub const CKM_PBA_SHA1_WITH_SHA1_HMAC: CK_MECHANISM_TYPE = 0x000003C0;
+
+pub const CKM_WTLS_PRE_MASTER_KEY_GEN: CK_MECHANISM_TYPE = 0x000003D0;
+pub const CKM_WTLS_MASTER_KEY_DERIVE: CK_MECHANISM_TYPE = 0x000003D1;
+pub const CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC: CK_MECHANISM_TYPE = 0x000003D2;
+pub const CKM_WTLS_PRF: CK_MECHANISM_TYPE = 0x000003D3;
+pub const CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE: CK_MECHANISM_TYPE = 0x000003D4;
+pub const CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE: CK_MECHANISM_TYPE = 0x000003D5;
+
+pub const CKM_TLS10_MAC_SERVER: CK_MECHANISM_TYPE = 0x000003D6;
+pub const CKM_TLS10_MAC_CLIENT: CK_MECHANISM_TYPE = 0x000003D7;
+pub const CKM_TLS12_MAC: CK_MECHANISM_TYPE = 0x000003D8;
+pub const CKM_TLS12_KDF: CK_MECHANISM_TYPE = 0x000003D9;
+pub const CKM_TLS12_MASTER_KEY_DERIVE: CK_MECHANISM_TYPE = 0x000003E0;
+pub const CKM_TLS12_KEY_AND_MAC_DERIVE: CK_MECHANISM_TYPE = 0x000003E1;
+pub const CKM_TLS12_MASTER_KEY_DERIVE_DH: CK_MECHANISM_TYPE = 0x000003E2;
+pub const CKM_TLS12_KEY_SAFE_DERIVE: CK_MECHANISM_TYPE = 0x000003E3;
+pub const CKM_TLS_MAC: CK_MECHANISM_TYPE = 0x000003E4;
+pub const CKM_TLS_KDF: CK_MECHANISM_TYPE = 0x000003E5;
+
+pub const CKM_KEY_WRAP_LYNKS: CK_MECHANISM_TYPE = 0x00000400;
+pub const CKM_KEY_WRAP_SET_OAEP: CK_MECHANISM_TYPE = 0x00000401;
+
+pub const CKM_CMS_SIG: CK_MECHANISM_TYPE = 0x00000500;
+pub const CKM_KIP_DERIVE: CK_MECHANISM_TYPE = 0x00000510;
+pub const CKM_KIP_WRAP: CK_MECHANISM_TYPE = 0x00000511;
+pub const CKM_KIP_MAC: CK_MECHANISM_TYPE = 0x00000512;
+
+pub const CKM_CAMELLIA_KEY_GEN: CK_MECHANISM_TYPE = 0x00000550;
+pub const CKM_CAMELLIA_ECB: CK_MECHANISM_TYPE = 0x00000551;
+pub const CKM_CAMELLIA_CBC: CK_MECHANISM_TYPE = 0x00000552;
+pub const CKM_CAMELLIA_MAC: CK_MECHANISM_TYPE = 0x00000553;
+pub const CKM_CAMELLIA_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000554;
+pub const CKM_CAMELLIA_CBC_PAD: CK_MECHANISM_TYPE = 0x00000555;
+pub const CKM_CAMELLIA_ECB_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00000556;
+pub const CKM_CAMELLIA_CBC_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00000557;
+pub const CKM_CAMELLIA_CTR: CK_MECHANISM_TYPE = 0x00000558;
+
+pub const CKM_ARIA_KEY_GEN: CK_MECHANISM_TYPE = 0x00000560;
+pub const CKM_ARIA_ECB: CK_MECHANISM_TYPE = 0x00000561;
+pub const CKM_ARIA_CBC: CK_MECHANISM_TYPE = 0x00000562;
+pub const CKM_ARIA_MAC: CK_MECHANISM_TYPE = 0x00000563;
+pub const CKM_ARIA_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000564;
+pub const CKM_ARIA_CBC_PAD: CK_MECHANISM_TYPE = 0x00000565;
+pub const CKM_ARIA_ECB_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00000566;
+pub const CKM_ARIA_CBC_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00000567;
+
+pub const CKM_SEED_KEY_GEN: CK_MECHANISM_TYPE = 0x00000650;
+pub const CKM_SEED_ECB: CK_MECHANISM_TYPE = 0x00000651;
+pub const CKM_SEED_CBC: CK_MECHANISM_TYPE = 0x00000652;
+pub const CKM_SEED_MAC: CK_MECHANISM_TYPE = 0x00000653;
+pub const CKM_SEED_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00000654;
+pub const CKM_SEED_CBC_PAD: CK_MECHANISM_TYPE = 0x00000655;
+pub const CKM_SEED_ECB_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00000656;
+pub const CKM_SEED_CBC_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00000657;
+
+pub const CKM_SKIPJACK_KEY_GEN: CK_MECHANISM_TYPE = 0x00001000;
+pub const CKM_SKIPJACK_ECB64: CK_MECHANISM_TYPE = 0x00001001;
+pub const CKM_SKIPJACK_CBC64: CK_MECHANISM_TYPE = 0x00001002;
+pub const CKM_SKIPJACK_OFB64: CK_MECHANISM_TYPE = 0x00001003;
+pub const CKM_SKIPJACK_CFB64: CK_MECHANISM_TYPE = 0x00001004;
+pub const CKM_SKIPJACK_CFB32: CK_MECHANISM_TYPE = 0x00001005;
+pub const CKM_SKIPJACK_CFB16: CK_MECHANISM_TYPE = 0x00001006;
+pub const CKM_SKIPJACK_CFB8: CK_MECHANISM_TYPE = 0x00001007;
+pub const CKM_SKIPJACK_WRAP: CK_MECHANISM_TYPE = 0x00001008;
+pub const CKM_SKIPJACK_PRIVATE_WRAP: CK_MECHANISM_TYPE = 0x00001009;
+pub const CKM_SKIPJACK_RELAYX: CK_MECHANISM_TYPE = 0x0000100a;
+pub const CKM_KEA_KEY_PAIR_GEN: CK_MECHANISM_TYPE = 0x00001010;
+pub const CKM_KEA_KEY_DERIVE: CK_MECHANISM_TYPE = 0x00001011;
+pub const CKM_KEA_DERIVE: CK_MECHANISM_TYPE = 0x00001012;
+pub const CKM_FORTEZZA_TIMESTAMP: CK_MECHANISM_TYPE = 0x00001020;
+pub const CKM_BATON_KEY_GEN: CK_MECHANISM_TYPE = 0x00001030;
+pub const CKM_BATON_ECB128: CK_MECHANISM_TYPE = 0x00001031;
+pub const CKM_BATON_ECB96: CK_MECHANISM_TYPE = 0x00001032;
+pub const CKM_BATON_CBC128: CK_MECHANISM_TYPE = 0x00001033;
+pub const CKM_BATON_COUNTER: CK_MECHANISM_TYPE = 0x00001034;
+pub const CKM_BATON_SHUFFLE: CK_MECHANISM_TYPE = 0x00001035;
+pub const CKM_BATON_WRAP: CK_MECHANISM_TYPE = 0x00001036;
+
+pub const CKM_ECDSA_KEY_PAIR_GEN: CK_MECHANISM_TYPE = CKM_EC_KEY_PAIR_GEN;
+pub const CKM_EC_KEY_PAIR_GEN: CK_MECHANISM_TYPE = 0x00001040;
+
+pub const CKM_ECDSA: CK_MECHANISM_TYPE = 0x00001041;
+pub const CKM_ECDSA_SHA1: CK_MECHANISM_TYPE = 0x00001042;
+pub const CKM_ECDSA_SHA224: CK_MECHANISM_TYPE = 0x00001043;
+pub const CKM_ECDSA_SHA256: CK_MECHANISM_TYPE = 0x00001044;
+pub const CKM_ECDSA_SHA384: CK_MECHANISM_TYPE = 0x00001045;
+pub const CKM_ECDSA_SHA512: CK_MECHANISM_TYPE = 0x00001046;
+
+pub const CKM_ECDH1_DERIVE: CK_MECHANISM_TYPE = 0x00001050;
+pub const CKM_ECDH1_COFACTOR_DERIVE: CK_MECHANISM_TYPE = 0x00001051;
+pub const CKM_ECMQV_DERIVE: CK_MECHANISM_TYPE = 0x00001052;
+
+pub const CKM_ECDH_AES_KEY_WRAP: CK_MECHANISM_TYPE = 0x00001053;
+pub const CKM_RSA_AES_KEY_WRAP: CK_MECHANISM_TYPE = 0x00001054;
+
+pub const CKM_JUNIPER_KEY_GEN: CK_MECHANISM_TYPE = 0x00001060;
+pub const CKM_JUNIPER_ECB128: CK_MECHANISM_TYPE = 0x00001061;
+pub const CKM_JUNIPER_CBC128: CK_MECHANISM_TYPE = 0x00001062;
+pub const CKM_JUNIPER_COUNTER: CK_MECHANISM_TYPE = 0x00001063;
+pub const CKM_JUNIPER_SHUFFLE: CK_MECHANISM_TYPE = 0x00001064;
+pub const CKM_JUNIPER_WRAP: CK_MECHANISM_TYPE = 0x00001065;
+pub const CKM_FASTHASH: CK_MECHANISM_TYPE = 0x00001070;
+
+pub const CKM_AES_KEY_GEN: CK_MECHANISM_TYPE = 0x00001080;
+pub const CKM_AES_ECB: CK_MECHANISM_TYPE = 0x00001081;
+pub const CKM_AES_CBC: CK_MECHANISM_TYPE = 0x00001082;
+pub const CKM_AES_MAC: CK_MECHANISM_TYPE = 0x00001083;
+pub const CKM_AES_MAC_GENERAL: CK_MECHANISM_TYPE = 0x00001084;
+pub const CKM_AES_CBC_PAD: CK_MECHANISM_TYPE = 0x00001085;
+pub const CKM_AES_CTR: CK_MECHANISM_TYPE = 0x00001086;
+pub const CKM_AES_GCM: CK_MECHANISM_TYPE = 0x00001087;
+pub const CKM_AES_CCM: CK_MECHANISM_TYPE = 0x00001088;
+pub const CKM_AES_CTS: CK_MECHANISM_TYPE = 0x00001089;
+pub const CKM_AES_CMAC: CK_MECHANISM_TYPE = 0x0000108A;
+pub const CKM_AES_CMAC_GENERAL: CK_MECHANISM_TYPE = 0x0000108B;
+
+pub const CKM_AES_XCBC_MAC: CK_MECHANISM_TYPE = 0x0000108C;
+pub const CKM_AES_XCBC_MAC_96: CK_MECHANISM_TYPE = 0x0000108D;
+pub const CKM_AES_GMAC: CK_MECHANISM_TYPE = 0x0000108E;
+
+pub const CKM_BLOWFISH_KEY_GEN: CK_MECHANISM_TYPE = 0x00001090;
+pub const CKM_BLOWFISH_CBC: CK_MECHANISM_TYPE = 0x00001091;
+pub const CKM_TWOFISH_KEY_GEN: CK_MECHANISM_TYPE = 0x00001092;
+pub const CKM_TWOFISH_CBC: CK_MECHANISM_TYPE = 0x00001093;
+pub const CKM_BLOWFISH_CBC_PAD: CK_MECHANISM_TYPE = 0x00001094;
+pub const CKM_TWOFISH_CBC_PAD: CK_MECHANISM_TYPE = 0x00001095;
+
+pub const CKM_DES_ECB_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00001100;
+pub const CKM_DES_CBC_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00001101;
+pub const CKM_DES3_ECB_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00001102;
+pub const CKM_DES3_CBC_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00001103;
+pub const CKM_AES_ECB_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00001104;
+pub const CKM_AES_CBC_ENCRYPT_DATA: CK_MECHANISM_TYPE = 0x00001105;
+
+pub const CKM_GOSTR3410_KEY_PAIR_GEN: CK_MECHANISM_TYPE = 0x00001200;
+pub const CKM_GOSTR3410: CK_MECHANISM_TYPE = 0x00001201;
+pub const CKM_GOSTR3410_WITH_GOSTR3411: CK_MECHANISM_TYPE = 0x00001202;
+pub const CKM_GOSTR3410_KEY_WRAP: CK_MECHANISM_TYPE = 0x00001203;
+pub const CKM_GOSTR3410_DERIVE: CK_MECHANISM_TYPE = 0x00001204;
+pub const CKM_GOSTR3411: CK_MECHANISM_TYPE = 0x00001210;
+pub const CKM_GOSTR3411_HMAC: CK_MECHANISM_TYPE = 0x00001211;
+pub const CKM_GOST28147_KEY_GEN: CK_MECHANISM_TYPE = 0x00001220;
+pub const CKM_GOST28147_ECB: CK_MECHANISM_TYPE = 0x00001221;
+pub const CKM_GOST28147: CK_MECHANISM_TYPE = 0x00001222;
+pub const CKM_GOST28147_MAC: CK_MECHANISM_TYPE = 0x00001223;
+pub const CKM_GOST28147_KEY_WRAP: CK_MECHANISM_TYPE = 0x00001224;
+
+pub const CKM_DSA_PARAMETER_GEN: CK_MECHANISM_TYPE = 0x00002000;
+pub const CKM_DH_PKCS_PARAMETER_GEN: CK_MECHANISM_TYPE = 0x00002001;
+pub const CKM_X9_42_DH_PARAMETER_GEN: CK_MECHANISM_TYPE = 0x00002002;
+pub const CKM_DSA_PROBABLISTIC_PARAMETER_GEN: CK_MECHANISM_TYPE = 0x00002003;
+pub const CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN: CK_MECHANISM_TYPE = 0x00002004;
+
+pub const CKM_AES_OFB: CK_MECHANISM_TYPE = 0x00002104;
+pub const CKM_AES_CFB64: CK_MECHANISM_TYPE = 0x00002105;
+pub const CKM_AES_CFB8: CK_MECHANISM_TYPE = 0x00002106;
+pub const CKM_AES_CFB128: CK_MECHANISM_TYPE = 0x00002107;
+
+pub const CKM_AES_CFB1: CK_MECHANISM_TYPE = 0x00002108;
+/// WAS: 0x00001090
+pub const CKM_AES_KEY_WRAP: CK_MECHANISM_TYPE = 0x00002109;
+/// WAS: 0x00001091
+pub const CKM_AES_KEY_WRAP_PAD: CK_MECHANISM_TYPE = 0x0000210A;
+
+pub const CKM_RSA_PKCS_TPM_1_1: CK_MECHANISM_TYPE = 0x00004001;
+pub const CKM_RSA_PKCS_OAEP_TPM_1_1: CK_MECHANISM_TYPE = 0x00004002;
+
+pub const CKM_VENDOR_DEFINED: CK_MECHANISM_TYPE = 0x80000000;
+
+pub type CK_MECHANISM_TYPE_PTR = *mut CK_MECHANISM_TYPE;
+
+
+/// CK_MECHANISM is a structure that specifies a particular
+/// mechanism
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_MECHANISM {
+ pub mechanism: CK_MECHANISM_TYPE,
+ pub pParameter: CK_VOID_PTR,
+ /// in bytes
+ pub ulParameterLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_MECHANISM);
+
+pub type CK_MECHANISM_PTR = *mut CK_MECHANISM;
+
+/// CK_MECHANISM_INFO provides information about a particular
+/// mechanism
+cryptoki_aligned! {
+ #[derive(Debug, Default, Copy)]
+ pub struct CK_MECHANISM_INFO {
+ pub ulMinKeySize: CK_ULONG,
+ pub ulMaxKeySize: CK_ULONG,
+ pub flags: CK_FLAGS,
+ }
+}
+packed_clone!(CK_MECHANISM_INFO);
+
+/// The flags are defined as follows:
+pub const CKF_HW: CK_FLAGS = 0x00000001; /* performed by HW */
+
+/// Specify whether or not a mechanism can be used for a particular task
+pub const CKF_ENCRYPT: CK_FLAGS = 0x00000100;
+pub const CKF_DECRYPT: CK_FLAGS = 0x00000200;
+pub const CKF_DIGEST: CK_FLAGS = 0x00000400;
+pub const CKF_SIGN: CK_FLAGS = 0x00000800;
+pub const CKF_SIGN_RECOVER: CK_FLAGS = 0x00001000;
+pub const CKF_VERIFY: CK_FLAGS = 0x00002000;
+pub const CKF_VERIFY_RECOVER: CK_FLAGS = 0x00004000;
+pub const CKF_GENERATE: CK_FLAGS = 0x00008000;
+pub const CKF_GENERATE_KEY_PAIR: CK_FLAGS = 0x00010000;
+pub const CKF_WRAP: CK_FLAGS = 0x00020000;
+pub const CKF_UNWRAP: CK_FLAGS = 0x00040000;
+pub const CKF_DERIVE: CK_FLAGS = 0x00080000;
+
+/// Describe a token's EC capabilities not available in mechanism
+/// information.
+pub const CKF_EC_F_P: CK_FLAGS = 0x00100000;
+pub const CKF_EC_F_2M: CK_FLAGS = 0x00200000;
+pub const CKF_EC_ECPARAMETERS: CK_FLAGS = 0x00400000;
+pub const CKF_EC_NAMEDCURVE: CK_FLAGS = 0x00800000;
+pub const CKF_EC_UNCOMPRESS: CK_FLAGS = 0x01000000;
+pub const CKF_EC_COMPRESS: CK_FLAGS = 0x02000000;
+
+pub const CKF_EXTENSION: CK_FLAGS = 0x80000000;
+
+pub type CK_MECHANISM_INFO_PTR = *mut CK_MECHANISM_INFO;
+
+/// CK_RV is a value that identifies the return value of a
+/// Cryptoki function
+pub type CK_RV = CK_ULONG;
+pub const CKR_OK: CK_RV = 0x00000000;
+pub const CKR_CANCEL: CK_RV = 0x00000001;
+pub const CKR_HOST_MEMORY: CK_RV = 0x00000002;
+pub const CKR_SLOT_ID_INVALID: CK_RV = 0x00000003;
+pub const CKR_GENERAL_ERROR: CK_RV = 0x00000005;
+pub const CKR_FUNCTION_FAILED: CK_RV = 0x00000006;
+pub const CKR_ARGUMENTS_BAD: CK_RV = 0x00000007;
+pub const CKR_NO_EVENT: CK_RV = 0x00000008;
+pub const CKR_NEED_TO_CREATE_THREADS: CK_RV = 0x00000009;
+pub const CKR_CANT_LOCK: CK_RV = 0x0000000A;
+pub const CKR_ATTRIBUTE_READ_ONLY: CK_RV = 0x00000010;
+pub const CKR_ATTRIBUTE_SENSITIVE: CK_RV = 0x00000011;
+pub const CKR_ATTRIBUTE_TYPE_INVALID: CK_RV = 0x00000012;
+pub const CKR_ATTRIBUTE_VALUE_INVALID: CK_RV = 0x00000013;
+pub const CKR_ACTION_PROHIBITED: CK_RV = 0x0000001B;
+pub const CKR_DATA_INVALID: CK_RV = 0x00000020;
+pub const CKR_DATA_LEN_RANGE: CK_RV = 0x00000021;
+pub const CKR_DEVICE_ERROR: CK_RV = 0x00000030;
+pub const CKR_DEVICE_MEMORY: CK_RV = 0x00000031;
+pub const CKR_DEVICE_REMOVED: CK_RV = 0x00000032;
+pub const CKR_ENCRYPTED_DATA_INVALID: CK_RV = 0x00000040;
+pub const CKR_ENCRYPTED_DATA_LEN_RANGE: CK_RV = 0x00000041;
+pub const CKR_FUNCTION_CANCELED: CK_RV = 0x00000050;
+pub const CKR_FUNCTION_NOT_PARALLEL: CK_RV = 0x00000051;
+pub const CKR_FUNCTION_NOT_SUPPORTED: CK_RV = 0x00000054;
+pub const CKR_KEY_HANDLE_INVALID: CK_RV = 0x00000060;
+pub const CKR_KEY_SIZE_RANGE: CK_RV = 0x00000062;
+pub const CKR_KEY_TYPE_INCONSISTENT: CK_RV = 0x00000063;
+pub const CKR_KEY_NOT_NEEDED: CK_RV = 0x00000064;
+pub const CKR_KEY_CHANGED: CK_RV = 0x00000065;
+pub const CKR_KEY_NEEDED: CK_RV = 0x00000066;
+pub const CKR_KEY_INDIGESTIBLE: CK_RV = 0x00000067;
+pub const CKR_KEY_FUNCTION_NOT_PERMITTED: CK_RV = 0x00000068;
+pub const CKR_KEY_NOT_WRAPPABLE: CK_RV = 0x00000069;
+pub const CKR_KEY_UNEXTRACTABLE: CK_RV = 0x0000006A;
+pub const CKR_MECHANISM_INVALID: CK_RV = 0x00000070;
+pub const CKR_MECHANISM_PARAM_INVALID: CK_RV = 0x00000071;
+pub const CKR_OBJECT_HANDLE_INVALID: CK_RV = 0x00000082;
+pub const CKR_OPERATION_ACTIVE: CK_RV = 0x00000090;
+pub const CKR_OPERATION_NOT_INITIALIZED: CK_RV = 0x00000091;
+pub const CKR_PIN_INCORRECT: CK_RV = 0x000000A0;
+pub const CKR_PIN_INVALID: CK_RV = 0x000000A1;
+pub const CKR_PIN_LEN_RANGE: CK_RV = 0x000000A2;
+pub const CKR_PIN_EXPIRED: CK_RV = 0x000000A3;
+pub const CKR_PIN_LOCKED: CK_RV = 0x000000A4;
+pub const CKR_SESSION_CLOSED: CK_RV = 0x000000B0;
+pub const CKR_SESSION_COUNT: CK_RV = 0x000000B1;
+pub const CKR_SESSION_HANDLE_INVALID: CK_RV = 0x000000B3;
+pub const CKR_SESSION_PARALLEL_NOT_SUPPORTED: CK_RV = 0x000000B4;
+pub const CKR_SESSION_READ_ONLY: CK_RV = 0x000000B5;
+pub const CKR_SESSION_EXISTS: CK_RV = 0x000000B6;
+pub const CKR_SESSION_READ_ONLY_EXISTS: CK_RV = 0x000000B7;
+pub const CKR_SESSION_READ_WRITE_SO_EXISTS: CK_RV = 0x000000B8;
+pub const CKR_SIGNATURE_INVALID: CK_RV = 0x000000C0;
+pub const CKR_SIGNATURE_LEN_RANGE: CK_RV = 0x000000C1;
+pub const CKR_TEMPLATE_INCOMPLETE: CK_RV = 0x000000D0;
+pub const CKR_TEMPLATE_INCONSISTENT: CK_RV = 0x000000D1;
+pub const CKR_TOKEN_NOT_PRESENT: CK_RV = 0x000000E0;
+pub const CKR_TOKEN_NOT_RECOGNIZED: CK_RV = 0x000000E1;
+pub const CKR_TOKEN_WRITE_PROTECTED: CK_RV = 0x000000E2;
+pub const CKR_UNWRAPPING_KEY_HANDLE_INVALID: CK_RV = 0x000000F0;
+pub const CKR_UNWRAPPING_KEY_SIZE_RANGE: CK_RV = 0x000000F1;
+pub const CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: CK_RV = 0x000000F2;
+pub const CKR_USER_ALREADY_LOGGED_IN: CK_RV = 0x00000100;
+pub const CKR_USER_NOT_LOGGED_IN: CK_RV = 0x00000101;
+pub const CKR_USER_PIN_NOT_INITIALIZED: CK_RV = 0x00000102;
+pub const CKR_USER_TYPE_INVALID: CK_RV = 0x00000103;
+pub const CKR_USER_ANOTHER_ALREADY_LOGGED_IN: CK_RV = 0x00000104;
+pub const CKR_USER_TOO_MANY_TYPES: CK_RV = 0x00000105;
+pub const CKR_WRAPPED_KEY_INVALID: CK_RV = 0x00000110;
+pub const CKR_WRAPPED_KEY_LEN_RANGE: CK_RV = 0x00000112;
+pub const CKR_WRAPPING_KEY_HANDLE_INVALID: CK_RV = 0x00000113;
+pub const CKR_WRAPPING_KEY_SIZE_RANGE: CK_RV = 0x00000114;
+pub const CKR_WRAPPING_KEY_TYPE_INCONSISTENT: CK_RV = 0x00000115;
+pub const CKR_RANDOM_SEED_NOT_SUPPORTED: CK_RV = 0x00000120;
+pub const CKR_RANDOM_NO_RNG: CK_RV = 0x00000121;
+pub const CKR_DOMAIN_PARAMS_INVALID: CK_RV = 0x00000130;
+pub const CKR_CURVE_NOT_SUPPORTED: CK_RV = 0x00000140;
+pub const CKR_BUFFER_TOO_SMALL: CK_RV = 0x00000150;
+pub const CKR_SAVED_STATE_INVALID: CK_RV = 0x00000160;
+pub const CKR_INFORMATION_SENSITIVE: CK_RV = 0x00000170;
+pub const CKR_STATE_UNSAVEABLE: CK_RV = 0x00000180;
+pub const CKR_CRYPTOKI_NOT_INITIALIZED: CK_RV = 0x00000190;
+pub const CKR_CRYPTOKI_ALREADY_INITIALIZED: CK_RV = 0x00000191;
+pub const CKR_MUTEX_BAD: CK_RV = 0x000001A0;
+pub const CKR_MUTEX_NOT_LOCKED: CK_RV = 0x000001A1;
+pub const CKR_NEW_PIN_MODE: CK_RV = 0x000001B0;
+pub const CKR_NEXT_OTP: CK_RV = 0x000001B1;
+pub const CKR_EXCEEDED_MAX_ITERATIONS: CK_RV = 0x000001B5;
+pub const CKR_FIPS_SELF_TEST_FAILED: CK_RV = 0x000001B6;
+pub const CKR_LIBRARY_LOAD_FAILED: CK_RV = 0x000001B7;
+pub const CKR_PIN_TOO_WEAK: CK_RV = 0x000001B8;
+pub const CKR_PUBLIC_KEY_INVALID: CK_RV = 0x000001B9;
+pub const CKR_FUNCTION_REJECTED: CK_RV = 0x00000200;
+pub const CKR_VENDOR_DEFINED: CK_RV = 0x80000000;
+
+/// CK_NOTIFY is an application callback that processes events
+pub type CK_NOTIFY = Option<extern "C" fn(CK_SESSION_HANDLE, CK_NOTIFICATION, CK_VOID_PTR) -> CK_RV>;
+
+/// CK_FUNCTION_LIST is a structure holding a Cryptoki spec
+/// version and pointers of appropriate types to all the
+/// Cryptoki functions
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_FUNCTION_LIST {
+ pub version: CK_VERSION,
+ pub C_Initialize: Option<C_Initialize>,
+ pub C_Finalize: Option<C_Finalize>,
+ pub C_GetInfo: Option<C_GetInfo>,
+ pub C_GetFunctionList: Option<C_GetFunctionList>,
+ pub C_GetSlotList: Option<C_GetSlotList>,
+ pub C_GetSlotInfo: Option<C_GetSlotInfo>,
+ pub C_GetTokenInfo: Option<C_GetTokenInfo>,
+ pub C_GetMechanismList: Option<C_GetMechanismList>,
+ pub C_GetMechanismInfo: Option<C_GetMechanismInfo>,
+ pub C_InitToken: Option<C_InitToken>,
+ pub C_InitPIN: Option<C_InitPIN>,
+ pub C_SetPIN: Option<C_SetPIN>,
+ pub C_OpenSession: Option<C_OpenSession>,
+ pub C_CloseSession: Option<C_CloseSession>,
+ pub C_CloseAllSessions: Option<C_CloseAllSessions>,
+ pub C_GetSessionInfo: Option<C_GetSessionInfo>,
+ pub C_GetOperationState: Option<C_GetOperationState>,
+ pub C_SetOperationState: Option<C_SetOperationState>,
+ pub C_Login: Option<C_Login>,
+ pub C_Logout: Option<C_Logout>,
+ pub C_CreateObject: Option<C_CreateObject>,
+ pub C_CopyObject: Option<C_CopyObject>,
+ pub C_DestroyObject: Option<C_DestroyObject>,
+ pub C_GetObjectSize: Option<C_GetObjectSize>,
+ pub C_GetAttributeValue: Option<C_GetAttributeValue>,
+ pub C_SetAttributeValue: Option<C_SetAttributeValue>,
+ pub C_FindObjectsInit: Option<C_FindObjectsInit>,
+ pub C_FindObjects: Option<C_FindObjects>,
+ pub C_FindObjectsFinal: Option<C_FindObjectsFinal>,
+ pub C_EncryptInit: Option<C_EncryptInit>,
+ pub C_Encrypt: Option<C_Encrypt>,
+ pub C_EncryptUpdate: Option<C_EncryptUpdate>,
+ pub C_EncryptFinal: Option<C_EncryptFinal>,
+ pub C_DecryptInit: Option<C_DecryptInit>,
+ pub C_Decrypt: Option<C_Decrypt>,
+ pub C_DecryptUpdate: Option<C_DecryptUpdate>,
+ pub C_DecryptFinal: Option<C_DecryptFinal>,
+ pub C_DigestInit: Option<C_DigestInit>,
+ pub C_Digest: Option<C_Digest>,
+ pub C_DigestUpdate: Option<C_DigestUpdate>,
+ pub C_DigestKey: Option<C_DigestKey>,
+ pub C_DigestFinal: Option<C_DigestFinal>,
+ pub C_SignInit: Option<C_SignInit>,
+ pub C_Sign: Option<C_Sign>,
+ pub C_SignUpdate: Option<C_SignUpdate>,
+ pub C_SignFinal: Option<C_SignFinal>,
+ pub C_SignRecoverInit: Option<C_SignRecoverInit>,
+ pub C_SignRecover: Option<C_SignRecover>,
+ pub C_VerifyInit: Option<C_VerifyInit>,
+ pub C_Verify: Option<C_Verify>,
+ pub C_VerifyUpdate: Option<C_VerifyUpdate>,
+ pub C_VerifyFinal: Option<C_VerifyFinal>,
+ pub C_VerifyRecoverInit: Option<C_VerifyRecoverInit>,
+ pub C_VerifyRecover: Option<C_VerifyRecover>,
+ pub C_DigestEncryptUpdate: Option<C_DigestEncryptUpdate>,
+ pub C_DecryptDigestUpdate: Option<C_DecryptDigestUpdate>,
+ pub C_SignEncryptUpdate: Option<C_SignEncryptUpdate>,
+ pub C_DecryptVerifyUpdate: Option<C_DecryptVerifyUpdate>,
+ pub C_GenerateKey: Option<C_GenerateKey>,
+ pub C_GenerateKeyPair: Option<C_GenerateKeyPair>,
+ pub C_WrapKey: Option<C_WrapKey>,
+ pub C_UnwrapKey: Option<C_UnwrapKey>,
+ pub C_DeriveKey: Option<C_DeriveKey>,
+ pub C_SeedRandom: Option<C_SeedRandom>,
+ pub C_GenerateRandom: Option<C_GenerateRandom>,
+ pub C_GetFunctionStatus: Option<C_GetFunctionStatus>,
+ pub C_CancelFunction: Option<C_CancelFunction>,
+ pub C_WaitForSlotEvent: Option<C_WaitForSlotEvent>,
+ }
+}
+packed_clone!(CK_FUNCTION_LIST);
+pub type CK_FUNCTION_LIST_PTR = *mut CK_FUNCTION_LIST;
+pub type CK_FUNCTION_LIST_PTR_PTR = *mut CK_FUNCTION_LIST_PTR;
+
+/// CK_CREATEMUTEX is an application callback for creating a
+/// mutex object
+pub type CK_CREATEMUTEX = Option<extern "C" fn(CK_VOID_PTR_PTR) -> CK_RV>;
+/// CK_DESTROYMUTEX is an application callback for destroying a
+/// mutex object
+pub type CK_DESTROYMUTEX = Option<extern "C" fn(CK_VOID_PTR) -> CK_RV>;
+/// CK_LOCKMUTEX is an application callback for locking a mutex
+pub type CK_LOCKMUTEX = Option<extern "C" fn(CK_VOID_PTR) -> CK_RV>;
+/// CK_UNLOCKMUTEX is an application callback for unlocking a
+/// mutex
+pub type CK_UNLOCKMUTEX = Option<extern "C" fn(CK_VOID_PTR) -> CK_RV>;
+
+/// CK_C_INITIALIZE_ARGS provides the optional arguments to
+/// C_Initialize
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_C_INITIALIZE_ARGS {
+ pub CreateMutex: CK_CREATEMUTEX,
+ pub DestroyMutex: CK_DESTROYMUTEX,
+ pub LockMutex: CK_LOCKMUTEX,
+ pub UnlockMutex: CK_UNLOCKMUTEX,
+ pub flags: CK_FLAGS,
+ pub pReserved: CK_VOID_PTR,
+ }
+}
+packed_clone!(CK_C_INITIALIZE_ARGS);
+
+// TODO: we need to make this the default and implement a new
+// function
+impl CK_C_INITIALIZE_ARGS {
+ pub fn new() -> CK_C_INITIALIZE_ARGS {
+ CK_C_INITIALIZE_ARGS {
+ flags: CKF_OS_LOCKING_OK,
+ CreateMutex: None,
+ DestroyMutex: None,
+ LockMutex: None,
+ UnlockMutex: None,
+ pReserved: ptr::null_mut(),
+ }
+ }
+}
+
+pub const CKF_LIBRARY_CANT_CREATE_OS_THREADS: CK_FLAGS = 0x00000001;
+pub const CKF_OS_LOCKING_OK: CK_FLAGS = 0x00000002;
+
+pub type CK_C_INITIALIZE_ARGS_PTR = *mut CK_C_INITIALIZE_ARGS;
+
+/// CKF_DONT_BLOCK is for the function C_WaitForSlotEvent
+pub const CKF_DONT_BLOCK: CK_FLAGS = 1;
+
+/// CK_RSA_PKCS_MGF_TYPE is used to indicate the Message
+/// Generation Function (MGF) applied to a message block when
+/// formatting a message block for the PKCS #1 OAEP encryption
+/// scheme.
+pub type CK_RSA_PKCS_MGF_TYPE = CK_ULONG;
+
+pub type CK_RSA_PKCS_MGF_TYPE_PTR = *mut CK_RSA_PKCS_MGF_TYPE;
+
+/// The following MGFs are defined
+pub const CKG_MGF1_SHA1: CK_RSA_PKCS_MGF_TYPE = 0x00000001;
+pub const CKG_MGF1_SHA256: CK_RSA_PKCS_MGF_TYPE = 0x00000002;
+pub const CKG_MGF1_SHA384: CK_RSA_PKCS_MGF_TYPE = 0x00000003;
+pub const CKG_MGF1_SHA512: CK_RSA_PKCS_MGF_TYPE = 0x00000004;
+pub const CKG_MGF1_SHA224: CK_RSA_PKCS_MGF_TYPE = 0x00000005;
+
+/// CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
+/// of the encoding parameter when formatting a message block
+/// for the PKCS #1 OAEP encryption scheme.
+pub type CK_RSA_PKCS_OAEP_SOURCE_TYPE = CK_ULONG;
+
+pub type CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR = *mut CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+/// The following encoding parameter sources are defined
+pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 0x00000001;
+
+/// CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+/// CKM_RSA_PKCS_OAEP mechanism.
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_RSA_PKCS_OAEP_PARAMS {
+ pub hashAlg: CK_MECHANISM_TYPE,
+ pub mgf: CK_RSA_PKCS_MGF_TYPE,
+ pub source: CK_RSA_PKCS_OAEP_SOURCE_TYPE,
+ pub pSourceData: CK_VOID_PTR,
+ pub ulSourceDataLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_RSA_PKCS_OAEP_PARAMS);
+
+pub type CK_RSA_PKCS_OAEP_PARAMS_PTR = *mut CK_RSA_PKCS_OAEP_PARAMS;
+
+/// CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
+/// CKM_RSA_PKCS_PSS mechanism(s).
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_RSA_PKCS_PSS_PARAMS {
+ pub hashAlg: CK_MECHANISM_TYPE,
+ pub mgf: CK_RSA_PKCS_MGF_TYPE,
+ pub sLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_RSA_PKCS_PSS_PARAMS);
+
+pub type CK_RSA_PKCS_PSS_PARAMS_PTR = *mut CK_RSA_PKCS_PSS_PARAMS;
+
+pub type CK_EC_KDF_TYPE = CK_ULONG;
+
+/* The following EC Key Derivation Functions are defined */
+pub const CKD_NULL: CK_EC_KDF_TYPE = 0x00000001;
+pub const CKD_SHA1_KDF: CK_EC_KDF_TYPE = 0x00000002;
+
+/* The following X9.42 DH key derivation functions are defined */
+pub const CKD_SHA1_KDF_ASN1: CK_X9_42_DH_KDF_TYPE = 0x00000003;
+pub const CKD_SHA1_KDF_CONCATENATE: CK_X9_42_DH_KDF_TYPE = 0x00000004;
+pub const CKD_SHA224_KDF: CK_X9_42_DH_KDF_TYPE = 0x00000005;
+pub const CKD_SHA256_KDF: CK_X9_42_DH_KDF_TYPE = 0x00000006;
+pub const CKD_SHA384_KDF: CK_X9_42_DH_KDF_TYPE = 0x00000007;
+pub const CKD_SHA512_KDF: CK_X9_42_DH_KDF_TYPE = 0x00000008;
+pub const CKD_CPDIVERSIFY_KDF: CK_X9_42_DH_KDF_TYPE = 0x00000009;
+
+/// CK_ECDH1_DERIVE_PARAMS provides the parameters to the
+/// CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
+/// where each party contributes one key pair.
+cryptoki_aligned! {
+ pub struct CK_ECDH1_DERIVE_PARAMS {
+ pub kdf: CK_EC_KDF_TYPE,
+ pub ulSharedDataLen: CK_ULONG,
+ pub pSharedData: CK_BYTE_PTR,
+ pub ulPublicDataLen: CK_ULONG,
+ pub pPublicData: CK_BYTE_PTR,
+ }
+}
+
+pub type CK_ECDH1_DERIVE_PARAMS_PTR = *mut CK_ECDH1_DERIVE_PARAMS;
+
+/// CK_ECDH2_DERIVE_PARAMS provides the parameters to the
+/// CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs.
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_ECDH2_DERIVE_PARAMS {
+ pub kdf: CK_EC_KDF_TYPE,
+ pub ulSharedDataLen: CK_ULONG,
+ pub pSharedData: CK_BYTE_PTR,
+ pub ulPublicDataLen: CK_ULONG,
+ pub pPublicData: CK_BYTE_PTR,
+ pub ulPrivateDataLen: CK_ULONG,
+ pub hPrivateData: CK_OBJECT_HANDLE,
+ pub ulPublicDataLen2: CK_ULONG,
+ pub pPublicData2: CK_BYTE_PTR,
+ }
+}
+packed_clone!(CK_ECDH2_DERIVE_PARAMS);
+
+pub type CK_ECDH2_DERIVE_PARAMS_PTR = *mut CK_ECDH2_DERIVE_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_ECMQV_DERIVE_PARAMS {
+ pub kdf: CK_EC_KDF_TYPE,
+ pub ulSharedDataLen: CK_ULONG,
+ pub pSharedData: CK_BYTE_PTR,
+ pub ulPublicDataLen: CK_ULONG,
+ pub pPublicData: CK_BYTE_PTR,
+ pub ulPrivateDataLen: CK_ULONG,
+ pub hPrivateData: CK_OBJECT_HANDLE,
+ pub ulPublicDataLen2: CK_ULONG,
+ pub pPublicData2: CK_BYTE_PTR,
+ pub publicKey: CK_OBJECT_HANDLE,
+ }
+}
+packed_clone!(CK_ECMQV_DERIVE_PARAMS);
+
+pub type CK_ECMQV_DERIVE_PARAMS_PTR = *mut CK_ECMQV_DERIVE_PARAMS;
+
+/// Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
+/// CKM_X9_42_DH_PARAMETER_GEN mechanisms
+pub type CK_X9_42_DH_KDF_TYPE = CK_ULONG;
+pub type CK_X9_42_DH_KDF_TYPE_PTR = *mut CK_X9_42_DH_KDF_TYPE;
+
+/// CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
+/// CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
+/// contributes one key pair
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_X9_42_DH1_DERIVE_PARAMS {
+ pub kdf: CK_X9_42_DH_KDF_TYPE,
+ pub ulOtherInfoLen: CK_ULONG,
+ pub pOtherInfo: CK_BYTE_PTR,
+ pub ulPublicDataLen: CK_ULONG,
+ pub pPublicData: CK_BYTE_PTR,
+ }
+}
+packed_clone!(CK_X9_42_DH1_DERIVE_PARAMS);
+
+pub type CK_X9_42_DH1_DERIVE_PARAMS_PTR = *mut CK_X9_42_DH1_DERIVE_PARAMS;
+
+/// CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
+/// CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
+/// mechanisms, where each party contributes two key pairs
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_X9_42_DH2_DERIVE_PARAMS {
+ pub kdf: CK_X9_42_DH_KDF_TYPE,
+ pub ulOtherInfoLen: CK_ULONG,
+ pub pOtherInfo: CK_BYTE_PTR,
+ pub ulPublicDataLen: CK_ULONG,
+ pub pPublicData: CK_BYTE_PTR,
+ pub ulPrivateDataLen: CK_ULONG,
+ pub hPrivateData: CK_OBJECT_HANDLE,
+ pub ulPublicDataLen2: CK_ULONG,
+ pub pPublicData2: CK_BYTE_PTR,
+ }
+}
+packed_clone!(CK_X9_42_DH2_DERIVE_PARAMS);
+
+pub type CK_X9_42_DH2_DERIVE_PARAMS_PTR = *mut CK_X9_42_DH2_DERIVE_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_X9_42_MQV_DERIVE_PARAMS {
+ pub kdf: CK_X9_42_DH_KDF_TYPE,
+ pub ulOtherInfoLen: CK_ULONG,
+ pub pOtherInfo: CK_BYTE_PTR,
+ pub ulPublicDataLen: CK_ULONG,
+ pub pPublicData: CK_BYTE_PTR,
+ pub ulPrivateDataLen: CK_ULONG,
+ pub hPrivateData: CK_OBJECT_HANDLE,
+ pub ulPublicDataLen2: CK_ULONG,
+ pub pPublicData2: CK_BYTE_PTR,
+ pub publicKey: CK_OBJECT_HANDLE,
+ }
+}
+packed_clone!(CK_X9_42_MQV_DERIVE_PARAMS);
+
+pub type CK_X9_42_MQV_DERIVE_PARAMS_PTR = *mut CK_X9_42_MQV_DERIVE_PARAMS;
+
+/// CK_KEA_DERIVE_PARAMS provides the parameters to the
+/// CKM_KEA_DERIVE mechanism
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_KEA_DERIVE_PARAMS {
+ pub isSender: CK_BBOOL,
+ pub ulRandomLen: CK_ULONG,
+ pub pRandomA: CK_BYTE_PTR,
+ pub pRandomB: CK_BYTE_PTR,
+ pub ulPublicDataLen: CK_ULONG,
+ pub pPublicData: CK_BYTE_PTR,
+ }
+}
+packed_clone!(CK_KEA_DERIVE_PARAMS);
+
+pub type CK_KEA_DERIVE_PARAMS_PTR = *mut CK_KEA_DERIVE_PARAMS;
+
+/// CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
+/// CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
+/// holds the effective keysize
+pub type CK_RC2_PARAMS = CK_ULONG;
+
+pub type CK_RC2_PARAMS_PTR = *mut CK_RC2_PARAMS;
+
+
+/// CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
+/// mechanism
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_RC2_CBC_PARAMS {
+ /// effective bits (1-1024)
+ pub ulEffectiveBits: CK_ULONG,
+ /// IV for CBC mode
+ pub iv: [CK_BYTE; 8],
+ }
+}
+packed_clone!(CK_RC2_CBC_PARAMS);
+
+pub type CK_RC2_CBC_PARAMS_PTR = *mut CK_RC2_CBC_PARAMS;
+
+
+/// CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
+/// CKM_RC2_MAC_GENERAL mechanism
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_RC2_MAC_GENERAL_PARAMS {
+ /// effective bits (1-1024)
+ pub ulEffectiveBits: CK_ULONG,
+ /// Length of MAC in bytes
+ pub ulMacLength: CK_ULONG,
+ }
+}
+packed_clone!(CK_RC2_MAC_GENERAL_PARAMS);
+
+pub type CK_RC2_MAC_GENERAL_PARAMS_PTR = *mut CK_RC2_MAC_GENERAL_PARAMS;
+
+
+/// CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
+/// CKM_RC5_MAC mechanisms
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_RC5_PARAMS {
+ /// wordsize in bits
+ pub ulWordsize: CK_ULONG,
+ /// number of rounds
+ pub ulRounds: CK_ULONG,
+ }
+}
+packed_clone!(CK_RC5_PARAMS);
+
+pub type CK_RC5_PARAMS_PTR = *mut CK_RC5_PARAMS;
+
+
+/// CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
+/// mechanism
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_RC5_CBC_PARAMS {
+ /// wordsize in bits
+ pub ulWordsize: CK_ULONG,
+ /// number of rounds
+ pub ulRounds: CK_ULONG,
+ /// pointer to IV
+ pub pIv: CK_BYTE_PTR,
+ /// length of IV in bytes
+ pub ulIvLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_RC5_CBC_PARAMS);
+
+pub type CK_RC5_CBC_PARAMS_PTR = *mut CK_RC5_CBC_PARAMS;
+
+
+/// CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
+/// CKM_RC5_MAC_GENERAL mechanism
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_RC5_MAC_GENERAL_PARAMS {
+ /// wordsize in bits
+ pub ulWordsize: CK_ULONG,
+ /// number of rounds
+ pub ulRounds: CK_ULONG,
+ /// Length of MAC in bytes
+ pub ulMacLength: CK_ULONG,
+ }
+}
+packed_clone!(CK_RC5_MAC_GENERAL_PARAMS);
+
+pub type CK_RC5_MAC_GENERAL_PARAMS_PTR = *mut CK_RC5_MAC_GENERAL_PARAMS;
+
+/// CK_MAC_GENERAL_PARAMS provides the parameters to most block
+/// ciphers' MAC_GENERAL mechanisms. Its value is the length of
+/// the MAC
+pub type CK_MAC_GENERAL_PARAMS = CK_ULONG;
+
+pub type CK_MAC_GENERAL_PARAMS_PTR = *mut CK_MAC_GENERAL_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
+ pub iv: [CK_BYTE; 8],
+ pub pData: CK_BYTE_PTR,
+ pub length: CK_ULONG,
+ }
+}
+packed_clone!(CK_DES_CBC_ENCRYPT_DATA_PARAMS);
+
+pub type CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR = *mut CK_DES_CBC_ENCRYPT_DATA_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
+ pub iv: [CK_BYTE; 16],
+ pub pData: CK_BYTE_PTR,
+ pub length: CK_ULONG,
+ }
+}
+packed_clone!(CK_AES_CBC_ENCRYPT_DATA_PARAMS);
+
+pub type CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR = *mut CK_AES_CBC_ENCRYPT_DATA_PARAMS;
+
+/// CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
+/// CKM_SKIPJACK_PRIVATE_WRAP mechanism
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
+ pub ulPasswordLen: CK_ULONG,
+ pub pPassword: CK_BYTE_PTR,
+ pub ulPublicDataLen: CK_ULONG,
+ pub pPublicData: CK_BYTE_PTR,
+ pub ulPAndGLen: CK_ULONG,
+ pub ulQLen: CK_ULONG,
+ pub ulRandomLen: CK_ULONG,
+ pub pRandomA: CK_BYTE_PTR,
+ pub pPrimeP: CK_BYTE_PTR,
+ pub pBaseG: CK_BYTE_PTR,
+ pub pSubprimeQ: CK_BYTE_PTR,
+ }
+}
+packed_clone!(CK_SKIPJACK_PRIVATE_WRAP_PARAMS);
+
+pub type CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR = *mut CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
+
+
+/// CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
+/// CKM_SKIPJACK_RELAYX mechanism
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_SKIPJACK_RELAYX_PARAMS {
+ pub ulOldWrappedXLen: CK_ULONG,
+ pub pOldWrappedX: CK_BYTE_PTR,
+ pub ulOldPasswordLen: CK_ULONG,
+ pub pOldPassword: CK_BYTE_PTR,
+ pub ulOldPublicDataLen: CK_ULONG,
+ pub pOldPublicData: CK_BYTE_PTR,
+ pub ulOldRandomLen: CK_ULONG,
+ pub pOldRandomA: CK_BYTE_PTR,
+ pub ulNewPasswordLen: CK_ULONG,
+ pub pNewPassword: CK_BYTE_PTR,
+ pub ulNewPublicDataLen: CK_ULONG,
+ pub pNewPublicData: CK_BYTE_PTR,
+ pub ulNewRandomLen: CK_ULONG,
+ pub pNewRandomA: CK_BYTE_PTR,
+ }
+}
+packed_clone!(CK_SKIPJACK_RELAYX_PARAMS);
+
+pub type CK_SKIPJACK_RELAYX_PARAMS_PTR = *mut CK_SKIPJACK_RELAYX_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_PBE_PARAMS {
+ pub pInitVector: CK_BYTE_PTR,
+ pub pPassword: CK_UTF8CHAR_PTR,
+ pub ulPasswordLen: CK_ULONG,
+ pub pSalt: CK_BYTE_PTR,
+ pub ulSaltLen: CK_ULONG,
+ pub ulIteration: CK_ULONG,
+ }
+}
+packed_clone!(CK_PBE_PARAMS);
+
+pub type CK_PBE_PARAMS_PTR = *mut CK_PBE_PARAMS;
+
+
+/// CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
+/// CKM_KEY_WRAP_SET_OAEP mechanism
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_KEY_WRAP_SET_OAEP_PARAMS {
+ /// block contents byte
+ pub bBC: CK_BYTE,
+ /// extra data
+ pub pX: CK_BYTE_PTR,
+ /// length of extra data in bytes
+ pub ulXLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_KEY_WRAP_SET_OAEP_PARAMS);
+
+pub type CK_KEY_WRAP_SET_OAEP_PARAMS_PTR = *mut CK_KEY_WRAP_SET_OAEP_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_SSL3_RANDOM_DATA {
+ pub pClientRandom: CK_BYTE_PTR,
+ pub ulClientRandomLen: CK_ULONG,
+ pub pServerRandom: CK_BYTE_PTR,
+ pub ulServerRandomLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_SSL3_RANDOM_DATA);
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+ pub RandomInfo: CK_SSL3_RANDOM_DATA,
+ pub pVersion: CK_VERSION_PTR,
+ }
+}
+packed_clone!(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
+
+pub type CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR = *mut CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_SSL3_KEY_MAT_OUT {
+ pub hClientMacSecret: CK_OBJECT_HANDLE,
+ pub hServerMacSecret: CK_OBJECT_HANDLE,
+ pub hClientKey: CK_OBJECT_HANDLE,
+ pub hServerKey: CK_OBJECT_HANDLE,
+ pub pIVClient: CK_BYTE_PTR,
+ pub pIVServer: CK_BYTE_PTR,
+ }
+}
+packed_clone!(CK_SSL3_KEY_MAT_OUT);
+
+pub type CK_SSL3_KEY_MAT_OUT_PTR = *mut CK_SSL3_KEY_MAT_OUT;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_SSL3_KEY_MAT_PARAMS {
+ pub ulMacSizeInBits: CK_ULONG,
+ pub ulKeySizeInBits: CK_ULONG,
+ pub ulIVSizeInBits: CK_ULONG,
+ pub bIsExport: CK_BBOOL,
+ pub RandomInfo: CK_SSL3_RANDOM_DATA,
+ pub pReturnedKeyMaterial: CK_SSL3_KEY_MAT_OUT_PTR,
+ }
+}
+packed_clone!(CK_SSL3_KEY_MAT_PARAMS);
+
+pub type CK_SSL3_KEY_MAT_PARAMS_PTR = *mut CK_SSL3_KEY_MAT_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_TLS_PRF_PARAMS {
+ pub pSeed: CK_BYTE_PTR,
+ pub ulSeedLen: CK_ULONG,
+ pub pLabel: CK_BYTE_PTR,
+ pub ulLabelLen: CK_ULONG,
+ pub pOutput: CK_BYTE_PTR,
+ pub pulOutputLen: CK_ULONG_PTR,
+ }
+}
+packed_clone!(CK_TLS_PRF_PARAMS);
+
+pub type CK_TLS_PRF_PARAMS_PTR = *mut CK_TLS_PRF_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_WTLS_RANDOM_DATA {
+ pub pClientRandom: CK_BYTE_PTR,
+ pub ulClientRandomLen: CK_ULONG,
+ pub pServerRandom: CK_BYTE_PTR,
+ pub ulServerRandomLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_WTLS_RANDOM_DATA);
+
+pub type CK_WTLS_RANDOM_DATA_PTR = *mut CK_WTLS_RANDOM_DATA;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
+ pub DigestMechanism: CK_MECHANISM_TYPE,
+ pub RandomInfo: CK_WTLS_RANDOM_DATA,
+ pub pVersion: CK_BYTE_PTR,
+ }
+}
+packed_clone!(CK_WTLS_MASTER_KEY_DERIVE_PARAMS);
+
+pub type CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR = *mut CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_WTLS_PRF_PARAMS {
+ pub DigestMechanism: CK_MECHANISM_TYPE,
+ pub pSeed: CK_BYTE_PTR,
+ pub ulSeedLen: CK_ULONG,
+ pub pLabel: CK_BYTE_PTR,
+ pub ulLabelLen: CK_ULONG,
+ pub pOutput: CK_BYTE_PTR,
+ pub pulOutputLen: CK_ULONG_PTR,
+ }
+}
+packed_clone!(CK_WTLS_PRF_PARAMS);
+
+pub type CK_WTLS_PRF_PARAMS_PTR = *mut CK_WTLS_PRF_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_WTLS_KEY_MAT_OUT {
+ pub hMacSecret: CK_OBJECT_HANDLE,
+ pub hKey: CK_OBJECT_HANDLE,
+ pub pIV: CK_BYTE_PTR,
+ }
+}
+packed_clone!(CK_WTLS_KEY_MAT_OUT);
+
+pub type CK_WTLS_KEY_MAT_OUT_PTR = *mut CK_WTLS_KEY_MAT_OUT;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_WTLS_KEY_MAT_PARAMS {
+ pub DigestMechanism: CK_MECHANISM_TYPE,
+ pub ulMacSizeInBits: CK_ULONG,
+ pub ulKeySizeInBits: CK_ULONG,
+ pub ulIVSizeInBits: CK_ULONG,
+ pub ulSequenceNumber: CK_ULONG,
+ pub bIsExport: CK_BBOOL,
+ pub RandomInfo: CK_WTLS_RANDOM_DATA,
+ pub pReturnedKeyMaterial: CK_WTLS_KEY_MAT_OUT_PTR,
+ }
+}
+packed_clone!(CK_WTLS_KEY_MAT_PARAMS);
+
+pub type CK_WTLS_KEY_MAT_PARAMS_PTR = *mut CK_WTLS_KEY_MAT_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_CMS_SIG_PARAMS {
+ pub certificateHandle: CK_OBJECT_HANDLE,
+ pub pSigningMechanism: CK_MECHANISM_PTR,
+ pub pDigestMechanism: CK_MECHANISM_PTR,
+ pub pContentType: CK_UTF8CHAR_PTR,
+ pub pRequestedAttributes: CK_BYTE_PTR,
+ pub ulRequestedAttributesLen: CK_ULONG,
+ pub pRequiredAttributes: CK_BYTE_PTR,
+ pub ulRequiredAttributesLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_CMS_SIG_PARAMS);
+
+pub type CK_CMS_SIG_PARAMS_PTR = *mut CK_CMS_SIG_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_KEY_DERIVATION_STRING_DATA {
+ pub pData: CK_BYTE_PTR,
+ pub ulLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_KEY_DERIVATION_STRING_DATA);
+
+pub type CK_KEY_DERIVATION_STRING_DATA_PTR = *mut CK_KEY_DERIVATION_STRING_DATA;
+
+
+/// The CK_EXTRACT_PARAMS is used for the
+/// CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
+/// of the base key should be used as the first bit of the
+/// derived key
+pub type CK_EXTRACT_PARAMS = CK_ULONG;
+
+pub type CK_EXTRACT_PARAMS_PTR = *mut CK_EXTRACT_PARAMS;
+
+/// CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
+/// indicate the Pseudo-Random Function (PRF) used to generate
+/// key bits using PKCS #5 PBKDF2.
+pub type CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE = CK_ULONG;
+
+pub type CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR = *mut CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
+pub const CKP_PKCS5_PBKD2_HMAC_SHA1: CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE = 0x00000001;
+pub const CKP_PKCS5_PBKD2_HMAC_GOSTR3411: CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE = 0x00000002;
+pub const CKP_PKCS5_PBKD2_HMAC_SHA224: CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE = 0x00000003;
+pub const CKP_PKCS5_PBKD2_HMAC_SHA256: CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE = 0x00000004;
+pub const CKP_PKCS5_PBKD2_HMAC_SHA384: CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE = 0x00000005;
+pub const CKP_PKCS5_PBKD2_HMAC_SHA512: CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE = 0x00000006;
+pub const CKP_PKCS5_PBKD2_HMAC_SHA512_224: CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE = 0x00000007;
+pub const CKP_PKCS5_PBKD2_HMAC_SHA512_256: CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE = 0x00000008;
+
+/// CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
+/// source of the salt value when deriving a key using PKCS #5
+/// PBKDF2.
+pub type CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = CK_ULONG;
+
+pub type CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR = *mut CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
+/// The following salt value sources are defined in PKCS #5 v2.0.
+pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 0x00000001;
+
+/// CK_PKCS5_PBKD2_PARAMS is a structure that provides the
+/// parameters to the CKM_PKCS5_PBKD2 mechanism.
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_PKCS5_PBKD2_PARAMS {
+ pub saltSource: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE,
+ pub pSaltSourceData: CK_VOID_PTR,
+ pub ulSaltSourceDataLen: CK_ULONG,
+ pub iterations: CK_ULONG,
+ pub prf: CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE,
+ pub pPrfData: CK_VOID_PTR,
+ pub ulPrfDataLen: CK_ULONG,
+ pub pPassword: CK_UTF8CHAR_PTR,
+ pub ulPasswordLen: CK_ULONG_PTR,
+ }
+}
+packed_clone!(CK_PKCS5_PBKD2_PARAMS);
+
+pub type CK_PKCS5_PBKD2_PARAMS_PTR = *mut CK_PKCS5_PBKD2_PARAMS;
+
+/// CK_PKCS5_PBKD2_PARAMS2 is a corrected version of the CK_PKCS5_PBKD2_PARAMS
+/// structure that provides the parameters to the CKM_PKCS5_PBKD2 mechanism
+/// noting that the ulPasswordLen field is a CK_ULONG and not a CK_ULONG_PTR.
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_PKCS5_PBKD2_PARAMS2 {
+ pub saltSource: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE,
+ pub pSaltSourceData: CK_VOID_PTR,
+ pub ulSaltSourceDataLen: CK_ULONG,
+ pub iterations: CK_ULONG,
+ pub prf: CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE,
+ pub pPrfData: CK_VOID_PTR,
+ pub ulPrfDataLen: CK_ULONG,
+ pub pPassword: CK_UTF8CHAR_PTR,
+ pub ulPasswordLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_PKCS5_PBKD2_PARAMS2);
+
+pub type CK_PKCS5_PBKD2_PARAMS2_PTR = *mut CK_PKCS5_PBKD2_PARAMS2;
+
+pub type CK_OTP_PARAM_TYPE = CK_ULONG;
+/// backward compatibility
+pub type CK_PARAM_TYPE = CK_OTP_PARAM_TYPE;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_OTP_PARAM {
+ pub paramType: CK_OTP_PARAM_TYPE,
+ pub pValue: CK_VOID_PTR,
+ pub ulValueLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_OTP_PARAM);
+
+pub type CK_OTP_PARAM_PTR = *mut CK_OTP_PARAM;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_OTP_PARAMS {
+ pub pParams: CK_OTP_PARAM_PTR,
+ pub ulCount: CK_ULONG,
+ }
+}
+packed_clone!(CK_OTP_PARAMS);
+
+pub type CK_OTP_PARAMS_PTR = *mut CK_OTP_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_OTP_SIGNATURE_INFO {
+ pub pParams: CK_OTP_PARAM_PTR,
+ pub ulCount: CK_ULONG,
+ }
+}
+packed_clone!(CK_OTP_SIGNATURE_INFO);
+
+pub type CK_OTP_SIGNATURE_INFO_PTR = *mut CK_OTP_SIGNATURE_INFO;
+
+pub const CK_OTP_VALUE: CK_ULONG = 0;
+pub const CK_OTP_PIN: CK_ULONG = 1;
+pub const CK_OTP_CHALLENGE: CK_ULONG = 2;
+pub const CK_OTP_TIME: CK_ULONG = 3;
+pub const CK_OTP_COUNTER: CK_ULONG = 4;
+pub const CK_OTP_FLAGS: CK_ULONG = 5;
+pub const CK_OTP_OUTPUT_LENGTH: CK_ULONG = 6;
+pub const CK_OTP_OUTPUT_FORMAT: CK_ULONG = 7;
+
+pub const CKF_NEXT_OTP: CK_FLAGS = 0x00000001;
+pub const CKF_EXCLUDE_TIME: CK_FLAGS = 0x00000002;
+pub const CKF_EXCLUDE_COUNTER: CK_FLAGS = 0x00000004;
+pub const CKF_EXCLUDE_CHALLENGE: CK_FLAGS = 0x00000008;
+pub const CKF_EXCLUDE_PIN: CK_FLAGS = 0x00000010;
+pub const CKF_USER_FRIENDLY_OTP: CK_FLAGS = 0x00000020;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_KIP_PARAMS {
+ pub pMechanism: CK_MECHANISM_PTR,
+ pub hKey: CK_OBJECT_HANDLE,
+ pub pSeed: CK_BYTE_PTR,
+ pub ulSeedLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_KIP_PARAMS);
+
+pub type CK_KIP_PARAMS_PTR = *mut CK_KIP_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_AES_CTR_PARAMS {
+ pub ulCounterBits: CK_ULONG,
+ pub cb: [CK_BYTE; 16],
+ }
+}
+packed_clone!(CK_AES_CTR_PARAMS);
+
+pub type CK_AES_CTR_PARAMS_PTR = *mut CK_AES_CTR_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_GCM_PARAMS {
+ pub pIv: CK_BYTE_PTR,
+ pub ulIvLen: CK_ULONG,
+ pub ulIvBits: CK_ULONG,
+ pub pAAD: CK_BYTE_PTR,
+ pub ulAADLen: CK_ULONG,
+ pub ulTagBits: CK_ULONG,
+ }
+}
+packed_clone!(CK_GCM_PARAMS);
+
+pub type CK_GCM_PARAMS_PTR = *mut CK_GCM_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_CCM_PARAMS {
+ pub ulDataLen: CK_ULONG,
+ pub pNonce: CK_BYTE_PTR,
+ pub ulNonceLen: CK_ULONG,
+ pub pAAD: CK_BYTE_PTR,
+ pub ulAADLen: CK_ULONG,
+ pub ulMACLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_CCM_PARAMS);
+
+pub type CK_CCM_PARAMS_PTR = *mut CK_CCM_PARAMS;
+
+/// Deprecated. Use CK_GCM_PARAMS
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_AES_GCM_PARAMS {
+ pub pIv: CK_BYTE_PTR,
+ pub ulIvLen: CK_ULONG,
+ pub ulIvBits: CK_ULONG,
+ pub pAAD: CK_BYTE_PTR,
+ pub ulAADLen: CK_ULONG,
+ pub ulTagBits: CK_ULONG,
+ }
+}
+packed_clone!(CK_AES_GCM_PARAMS);
+
+pub type CK_AES_GCM_PARAMS_PTR = *mut CK_AES_GCM_PARAMS;
+
+/// Deprecated. Use CK_CCM_PARAMS
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_AES_CCM_PARAMS {
+ pub ulDataLen: CK_ULONG,
+ pub pNonce: CK_BYTE_PTR,
+ pub ulNonceLen: CK_ULONG,
+ pub pAAD: CK_BYTE_PTR,
+ pub ulAADLen: CK_ULONG,
+ pub ulMACLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_AES_CCM_PARAMS);
+
+pub type CK_AES_CCM_PARAMS_PTR = *mut CK_AES_CCM_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_CAMELLIA_CTR_PARAMS {
+ pub ulCounterBits: CK_ULONG,
+ pub cb: [CK_BYTE; 16],
+ }
+}
+packed_clone!(CK_CAMELLIA_CTR_PARAMS);
+
+pub type CK_CAMELLIA_CTR_PARAMS_PTR = *mut CK_CAMELLIA_CTR_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
+ pub iv: [CK_BYTE; 16],
+ pub pData: CK_BYTE_PTR,
+ pub length: CK_ULONG,
+ }
+}
+packed_clone!(CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS);
+
+pub type CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR = *mut CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
+ pub iv: [CK_BYTE; 16],
+ pub pData: CK_BYTE_PTR,
+ pub length: CK_ULONG,
+ }
+}
+packed_clone!(CK_ARIA_CBC_ENCRYPT_DATA_PARAMS);
+
+pub type CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR = *mut CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_DSA_PARAMETER_GEN_PARAM {
+ pub hash: CK_MECHANISM_TYPE,
+ pub pSeed: CK_BYTE_PTR,
+ pub ulSeedLen: CK_ULONG,
+ pub ulIndex: CK_ULONG,
+ }
+}
+packed_clone!(CK_DSA_PARAMETER_GEN_PARAM);
+
+pub type CK_DSA_PARAMETER_GEN_PARAM_PTR = *mut CK_DSA_PARAMETER_GEN_PARAM;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_ECDH_AES_KEY_WRAP_PARAMS {
+ pub ulAESKeyBits: CK_ULONG,
+ pub kdf: CK_EC_KDF_TYPE,
+ pub ulSharedDataLen: CK_ULONG,
+ pub pSharedData: CK_BYTE_PTR,
+ }
+}
+packed_clone!(CK_ECDH_AES_KEY_WRAP_PARAMS);
+
+pub type CK_ECDH_AES_KEY_WRAP_PARAMS_PTR = *mut CK_ECDH_AES_KEY_WRAP_PARAMS;
+
+pub type CK_JAVA_MIDP_SECURITY_DOMAIN = CK_ULONG;
+
+pub type CK_CERTIFICATE_CATEGORY = CK_ULONG;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_RSA_AES_KEY_WRAP_PARAMS {
+ pub ulAESKeyBits: CK_ULONG,
+ pub pOAEPParams: CK_RSA_PKCS_OAEP_PARAMS_PTR,
+ }
+}
+packed_clone!(CK_RSA_AES_KEY_WRAP_PARAMS);
+
+pub type CK_RSA_AES_KEY_WRAP_PARAMS_PTR = *mut CK_RSA_AES_KEY_WRAP_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS {
+ pub RandomInfo: CK_SSL3_RANDOM_DATA,
+ pub pVersion: CK_VERSION_PTR,
+ pub prfHashMechanism: CK_MECHANISM_TYPE,
+ }
+}
+packed_clone!(CK_TLS12_MASTER_KEY_DERIVE_PARAMS);
+
+pub type CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR = *mut CK_TLS12_MASTER_KEY_DERIVE_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_TLS12_KEY_MAT_PARAMS {
+ pub ulMacSizeInBits: CK_ULONG,
+ pub ulKeySizeInBits: CK_ULONG,
+ pub ulIVSizeInBits: CK_ULONG,
+ pub bIsExport: CK_BBOOL,
+ pub RandomInfo: CK_SSL3_RANDOM_DATA,
+ pub pReturnedKeyMaterial: CK_SSL3_KEY_MAT_OUT_PTR,
+ pub prfHashMechanism: CK_MECHANISM_TYPE,
+ }
+}
+packed_clone!(CK_TLS12_KEY_MAT_PARAMS);
+
+pub type CK_TLS12_KEY_MAT_PARAMS_PTR = *mut CK_TLS12_KEY_MAT_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_TLS_KDF_PARAMS {
+ pub prfMechanism: CK_MECHANISM_TYPE,
+ pub pLabel: CK_BYTE_PTR,
+ pub ulLabelLength: CK_ULONG,
+ pub RandomInfo: CK_SSL3_RANDOM_DATA,
+ pub pContextData: CK_BYTE_PTR,
+ pub ulContextDataLength: CK_ULONG,
+ }
+}
+packed_clone!(CK_TLS_KDF_PARAMS);
+
+pub type CK_TLS_KDF_PARAMS_PTR = *mut CK_TLS_KDF_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_TLS_MAC_PARAMS {
+ pub prfHashMechanism: CK_MECHANISM_TYPE,
+ pub ulMacLength: CK_ULONG,
+ pub ulServerOrClient: CK_ULONG,
+ }
+}
+packed_clone!(CK_TLS_MAC_PARAMS);
+
+pub type CK_TLS_MAC_PARAMS_PTR = *mut CK_TLS_MAC_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_GOSTR3410_DERIVE_PARAMS {
+ pub kdf: CK_EC_KDF_TYPE,
+ pub pPublicData: CK_BYTE_PTR,
+ pub ulPublicDataLen: CK_ULONG,
+ pub pUKM: CK_BYTE_PTR,
+ pub ulUKMLen: CK_ULONG,
+ }
+}
+packed_clone!(CK_GOSTR3410_DERIVE_PARAMS);
+
+pub type CK_GOSTR3410_DERIVE_PARAMS_PTR = *mut CK_GOSTR3410_DERIVE_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_GOSTR3410_KEY_WRAP_PARAMS {
+ pub pWrapOID: CK_BYTE_PTR,
+ pub ulWrapOIDLen: CK_ULONG,
+ pub pUKM: CK_BYTE_PTR,
+ pub ulUKMLen: CK_ULONG,
+ pub hKey: CK_OBJECT_HANDLE,
+ }
+}
+packed_clone!(CK_GOSTR3410_KEY_WRAP_PARAMS);
+
+pub type CK_GOSTR3410_KEY_WRAP_PARAMS_PTR = *mut CK_GOSTR3410_KEY_WRAP_PARAMS;
+
+cryptoki_aligned! {
+ #[derive(Debug, Copy)]
+ pub struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS {
+ pub iv: [CK_BYTE; 16],
+ pub pData: CK_BYTE_PTR,
+ pub length: CK_ULONG,
+ }
+}
+packed_clone!(CK_SEED_CBC_ENCRYPT_DATA_PARAMS);
+
+pub type CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR = *mut CK_SEED_CBC_ENCRYPT_DATA_PARAMS;