This repository has been archived by the owner on Oct 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
session_impl.h
223 lines (205 loc) · 9.88 KB
/
session_impl.h
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef P11NET_SESSION_IMPL_H_
#define P11NET_SESSION_IMPL_H_
#include "session.h"
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include "p11net_factory.h"
#include "object.h"
#include "object_pool.h"
#include "net_utility.h"
#include "pkcs11/cryptoki.h"
namespace p11net {
class P11NetFactory;
class ObjectPool;
class NetUtility;
// SessionImpl is the interface for a PKCS #11 session. This component is
// responsible for maintaining session state including the state of any multi-
// part operations and any session objects. It is also responsible for
// executing all session-specific operations.
class SessionImpl : public Session {
public:
// The ownership and management of the pointers provided here are outside the
// scope of this class. Typically, the object pool will be managed by the slot
// manager and will be shared by all sessions associated with the same slot.
// The tpm and factory objects are typically singletons and shared across all
// sessions and slots.
SessionImpl(int slot_id,
std::shared_ptr<ObjectPool> token_object_pool,
std::shared_ptr<NetUtility> net_utility,
std::shared_ptr<P11NetFactory> factory,
std::shared_ptr<HandleGenerator> handle_generator,
bool is_read_only);
virtual ~SessionImpl();
// General state management.
virtual int GetSlot() const;
virtual CK_STATE GetState() const;
virtual bool IsReadOnly() const;
virtual bool IsOperationActive(OperationType type) const;
// Object management.
virtual CK_RV CreateObject(const CK_ATTRIBUTE_PTR attributes,
int num_attributes,
int* new_object_handle);
virtual CK_RV CopyObject(const CK_ATTRIBUTE_PTR attributes,
int num_attributes,
int object_handle,
int* new_object_handle);
virtual CK_RV DestroyObject(int object_handle);
virtual bool GetObject(int object_handle, const Object** object);
virtual bool GetModifiableObject(int object_handle, Object** object);
virtual bool FlushModifiableObject(Object* object);
virtual CK_RV FindObjectsInit(const CK_ATTRIBUTE_PTR attributes,
int num_attributes);
virtual CK_RV FindObjects(int max_object_count,
std::vector<int>* object_handles);
virtual CK_RV FindObjectsFinal();
// Cryptographic operations (encrypt, decrypt, digest, sign, verify).
virtual CK_RV OperationInit(OperationType operation,
CK_MECHANISM_TYPE mechanism,
const std::string& mechanism_parameter,
const Object* key);
virtual CK_RV OperationUpdate(OperationType operation,
const std::string& data_in,
int* required_out_length,
std::string* data_out);
virtual CK_RV OperationFinal(OperationType operation,
int* required_out_length,
std::string* data_out);
virtual void OperationCancel(OperationType operation);
virtual CK_RV VerifyFinal(const std::string& signature);
virtual CK_RV OperationSinglePart(OperationType operation,
const std::string& data_in,
int* required_out_length,
std::string* data_out);
// Key generation.
virtual CK_RV GenerateKey(CK_MECHANISM_TYPE mechanism,
const std::string& mechanism_parameter,
const CK_ATTRIBUTE_PTR attributes,
int num_attributes,
int* new_key_handle);
virtual CK_RV GenerateKeyPair(CK_MECHANISM_TYPE mechanism,
const std::string& mechanism_parameter,
const CK_ATTRIBUTE_PTR public_attributes,
int num_public_attributes,
const CK_ATTRIBUTE_PTR private_attributes,
int num_private_attributes,
int* new_public_key_handle,
int* new_private_key_handle);
// Random number generation.
virtual CK_RV SeedRandom(const std::string& seed);
virtual CK_RV GenerateRandom(int num_bytes, std::string* random_data);
// Waits for private objects to be loaded before returning.
virtual void WaitForPrivateObjects();
private:
struct OperationContext {
bool is_valid_; // Whether the contents of this structure are valid.
bool is_cipher_; // Set to true when cipher_context_ is valid.
bool is_digest_; // Set to true when digest_context_ is valid.
bool is_hmac_; // Set to true when hmac_context_ is valid.
bool is_incremental_; // Set when an incremental operation is performed.
bool is_finished_; // Set to true when the operation completes.
union {
EVP_CIPHER_CTX cipher_context_;
EVP_MD_CTX digest_context_;
HMAC_CTX hmac_context_;
};
std::string data_; // This can be used to queue input or output.
const Object* key_;
CK_MECHANISM_TYPE mechanism_;
std::string parameter_; // The mechanism parameter (if any).
OperationContext();
~OperationContext();
void Clear();
};
bool IsValidKeyType(OperationType operation,
CK_MECHANISM_TYPE mechanism,
CK_OBJECT_CLASS object_class,
CK_KEY_TYPE key_type);
bool IsValidMechanism(OperationType operation, CK_MECHANISM_TYPE mechanism);
CK_RV OperationUpdateInternal(OperationType operation,
const std::string& data_in,
int* required_out_length,
std::string* data_out);
CK_RV OperationFinalInternal(OperationType operation,
int* required_out_length,
std::string* data_out);
CK_RV CipherInit(bool is_encrypt,
CK_MECHANISM_TYPE mechanism,
const std::string& mechanism_parameter,
const Object* key);
CK_RV CipherUpdate(OperationContext* context,
const std::string& data_in,
int* required_out_length,
std::string* data_out);
CK_RV CipherFinal(OperationContext* context);
CK_RV CreateObjectInternal(const CK_ATTRIBUTE_PTR attributes,
int num_attributes,
const Object* copy_from_object,
int* new_object_handle);
bool GenerateDESKey(std::string* key_material);
bool GenerateKeyPairSoftware(int modulus_bits,
const std::string& public_exponent,
Object* public_object,
Object* private_object);
std::string GenerateRandomSoftware(int num_bytes);
std::string GetDERDigestInfo(CK_MECHANISM_TYPE mechanism);
// Provides operation output and handles the buffer-too-small case.
// The output data must be in context->data_.
// required_out_length - In: The maximum number of bytes that can be received.
// Out: The actual number of bytes to be received.
// data_out - Receives the output data if maximum >= actual.
CK_RV GetOperationOutput(OperationContext* context,
int* required_out_length,
std::string* data_out);
// Returns the key usage flag that must be set in order to perform the given
// operation (e.g. kEncrypt requires CKA_ENCRYPT to be TRUE).
CK_ATTRIBUTE_TYPE GetRequiredKeyUsage(OperationType operation);
bool GetTPMKeyHandle(const Object* key, int* key_handle);
bool LoadLegacyRootKeys();
bool IsHMAC(CK_MECHANISM_TYPE mechanism);
// Returns true if the given cipher mechanism uses padding.
bool IsPaddingEnabled(CK_MECHANISM_TYPE mechanism);
bool IsRSA(CK_MECHANISM_TYPE mechanism);
bool RSAEncrypt(OperationContext* context);
bool RSADecrypt(OperationContext* context);
bool RSASign(OperationContext* context);
CK_RV RSAVerify(OperationContext* context,
const std::string& digest,
const std::string& signature);
// Wraps the given private key using the TPM and deletes all sensitive
// attributes. This is called when a private key is imported. On success,
// the private key can only be accessed by the TPM.
CK_RV WrapPrivateKey(Object* object);
// Helpers to map PKCS #11 <--> OpenSSL.
std::string ConvertFromBIGNUM(const BIGNUM* bignum);
// Returns NULL if big_integer is empty.
BIGNUM* ConvertToBIGNUM(const std::string& big_integer);
// Always returns a non-NULL value.
RSA* CreateKeyFromObject(const Object* key_object);
const EVP_CIPHER* GetOpenSSLCipher(CK_MECHANISM_TYPE mechanism,
size_t key_size);
const EVP_MD* GetOpenSSLDigest(CK_MECHANISM_TYPE mechanism);
std::shared_ptr<P11NetFactory> factory_;
std::vector<int> find_results_;
size_t find_results_offset_;
bool find_results_valid_;
bool is_read_only_;
std::map<const Object*, int> object_tpm_handle_map_;
OperationContext operation_context_[kNumOperationTypes];
int slot_id_;
std::shared_ptr<ObjectPool> session_object_pool_;
std::shared_ptr<ObjectPool> token_object_pool_;
std::shared_ptr<NetUtility> net_utility_;
bool is_legacy_loaded_; // Tracks whether the legacy root keys are loaded.
int private_root_key_; // The legacy private root key.
int public_root_key_; // The legacy public root key.
DISALLOW_COPY_AND_ASSIGN(SessionImpl);
};
} // namespace p11net
#endif // P11NET_SESSION_IMPL_H_