diff options
Diffstat (limited to 'third_party/rust/pkcs11')
-rw-r--r-- | third_party/rust/pkcs11/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/pkcs11/Cargo.toml | 39 | ||||
-rw-r--r-- | third_party/rust/pkcs11/LICENSE | 202 | ||||
-rw-r--r-- | third_party/rust/pkcs11/NOTICE | 13 | ||||
-rw-r--r-- | third_party/rust/pkcs11/README.md | 46 | ||||
-rw-r--r-- | third_party/rust/pkcs11/rustfmt.toml | 81 | ||||
-rw-r--r-- | third_party/rust/pkcs11/src/errors.rs | 152 | ||||
-rw-r--r-- | third_party/rust/pkcs11/src/functions.rs | 760 | ||||
-rw-r--r-- | third_party/rust/pkcs11/src/lib.rs | 1298 | ||||
-rw-r--r-- | third_party/rust/pkcs11/src/tests.rs | 1552 | ||||
-rw-r--r-- | third_party/rust/pkcs11/src/types.rs | 2497 |
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(©able), + 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(©able), + 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; |