aboutsummaryrefslogtreecommitdiff
path: root/openssl/agent/pkcs11/private-key.hxx
blob: 967f0576ce1ea2dcb39a127463160aa900b342fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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