diff options
Diffstat (limited to 'openssl/agent/pkcs11/private-key.hxx')
-rw-r--r-- | openssl/agent/pkcs11/private-key.hxx | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/openssl/agent/pkcs11/private-key.hxx b/openssl/agent/pkcs11/private-key.hxx new file mode 100644 index 0000000..967f057 --- /dev/null +++ b/openssl/agent/pkcs11/private-key.hxx @@ -0,0 +1,95 @@ +// file : openssl/agent/pkcs11/private-key.hxx -*- C++ -*- +// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef OPENSSL_AGENT_PKCS11_PRIVATE_KEY_HXX +#define OPENSSL_AGENT_PKCS11_PRIVATE_KEY_HXX + +#include <openssl/types.hxx> +#include <openssl/utility.hxx> + +#include <openssl/agent/pkcs11/url.hxx> +#include <openssl/agent/pkcs11/pkcs11.hxx> + +namespace openssl +{ + namespace agent + { + namespace pkcs11 + { + // Unlocked private key. + // + // Keeps the authenticated session with the token containing the key. + // + // Note that the key should be configured not to require authentication + // of the sign operation. For Yubikey 4 this is achieved by passing the + // --pin-policy=never option to the yubico-piv-tool import-key command. + // + class private_key + { + public: + string description; + + // Open PKCS#11 authenticated session with the token containing the + // private key that matches the identity attributes using the + // specified access attributes. Throw invalid_argument if there is + // something wrong with the identity or access attributes. Throw + // runtime_error if the matching private key cannot be found, accessed + // or multiple keys match the criteria. + // + // The token PIN is expected to be specified either as the pin + // argument (preferred) or as the pin_value access attribute. The + // pin_source access attribute is ignored. The pin argument is + // normally allocated on the stack and is overwritten with zeros + // after the usage. Using the pin_value attribute is insecure (may + // stay in memory) and is discouraged unless for debugging and + // testing. + // + private_key (const identity&, + const access&, + const char* pin, + optional<simulate_outcome> = nullopt); + + // Create a special empty key that may not be used for any + // cryptographic operations. + // + private_key (); + + // Movable-only type. + // + private_key (private_key&&); + private_key& operator= (private_key&&); + private_key (const private_key&) = delete; + private_key& operator= (const private_key&) = delete; + + // Sign the data. Throw runtime_error if something goes wrong. + // + vector<char> + sign (const vector<char>&, + const optional<simulate_outcome>& = nullopt); + + bool + empty () const {return session_ == nullptr && !simulate_;} + + private: + using session_ptr = unique_ptr<CK_SESSION_HANDLE, + void (*)(CK_SESSION_HANDLE*)>; + session_ptr session_; + + CK_OBJECT_HANDLE handle_; // Meaningless if session_ is NULL. + + optional<simulate_outcome> simulate_; + + // Normally the signature buffer size is the private key length. + // However, calculating this length is not trivial and would require + // using libcrypto library. To avoid this we will start with the 256 + // bytes, doubling it while the sign operation complains about it, and + // cacheing the resulting size for future sign() calls. + // + CK_ULONG signature_size_ = 256; + }; + } + } +} + +#endif // OPENSSL_AGENT_PKCS11_PRIVATE_KEY_HXX |