Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cdoc/CDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ static constexpr Result results[] = {
{HASH_MISMATCH, "Hash mismatch"},
{CONFIGURATION_ERROR, "Configuration error"},
{NOT_FOUND, "Object not found"},
{INTERNAL_ERROR, "Internal error"},
{UNSPECIFIED_ERROR, "Unspecified error"},
};

Expand Down
4 changes: 4 additions & 0 deletions cdoc/CDoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ enum {
* @brief Object not found
*/
NOT_FOUND = -116,
/**
* @brief Internal error in libcdoc logic
*/
INTERNAL_ERROR = -117,
/**
* @brief Unspecified error
*/
Expand Down
211 changes: 138 additions & 73 deletions cdoc/CDocCipher.cpp

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions cdoc/CDocCipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ class CDOC_EXPORT CDocCipher
CDocCipher(const CDocCipher&) = delete;
CDocCipher(CDocCipher&&) = delete;

int Encrypt(ToolConf& conf, std::vector<libcdoc::RcptInfo>& recipients);
static int Encrypt(ToolConf& conf, std::vector<libcdoc::RcptInfo>& recipients);

int Decrypt(ToolConf& conf, const RcptInfo& recipient);
static int Decrypt(ToolConf& conf, RcptInfo& recipient);

int ReEncrypt(ToolConf& conf, const RcptInfo& lock_info, std::vector<libcdoc::RcptInfo>& recipients);
static int ReEncrypt(ToolConf& conf, RcptInfo& lock_info, std::vector<libcdoc::RcptInfo>& recipients);

void Locks(const char* file) const;
static void Locks(const char* file);

private:
int writer_push(CDocWriter& writer, const std::vector<libcdoc::Recipient>& keys, const std::vector<std::string>& files);
int Decrypt(const std::unique_ptr<CDocReader>& rdr, unsigned int lock_idx, const std::string& base_path);
static int writer_push(CDocWriter& writer, const std::vector<libcdoc::Recipient>& keys, const std::vector<std::string>& files);
static int Decrypt(const std::unique_ptr<CDocReader>& rdr, unsigned int lock_idx, const std::string& base_path);
};

}
Expand Down
35 changes: 29 additions & 6 deletions cdoc/PKCS11Backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ libcdoc::PKCS11Backend::Private::login(int slot, const std::vector<uint8_t>& pin
LOG_DBG("PKCS11:C_Login CANCELED");
break;
default:
LOG_DBG("PKCS11:C_Login {}", result);
LOG_DBG("PKCS11:C_Login {}", result);
f->C_CloseSession(session);
session = CK_INVALID_HANDLE;
return PKCS11_ERROR;
Expand Down Expand Up @@ -296,7 +296,10 @@ libcdoc::PKCS11Backend::useSecretKey(int slot, const std::vector<uint8_t>& pin,
}
std::vector<CK_OBJECT_HANDLE> handles = d->findObjects(d->session, CKO_SECRET_KEY, id, label, nullptr);
LOG_DBG("PKCS11: useSecretKey id={}; label={}; found {} keys", toHex(id), label, handles.size());
if (handles.empty() || (handles.size() != 1)) return CRYPTO_ERROR;
if (handles.empty() || (handles.size() != 1)) {
d->logout();
return CRYPTO_ERROR;
}
d->key = handles[0];
LOG_DBG("PKCS11: useSecretKey Using key {}", d->key);
return OK;
Expand All @@ -312,7 +315,10 @@ libcdoc::PKCS11Backend::usePrivateKey(int slot, const std::vector<uint8_t>& pin,
}
std::vector<CK_OBJECT_HANDLE> handles = d->findObjects(d->session, CKO_PRIVATE_KEY, id, label, nullptr);
LOG_DBG("PKCS11: usePrivateKey id={}; label={}; found {} keys", toHex(id), label, handles.size());
if (handles.size() != 1) return CRYPTO_ERROR;
if (handles.size() != 1) {
d->logout();
return CRYPTO_ERROR;
}
d->key = handles[0];
LOG_DBG("PKCS11: usePrivateKey Using key {}", d->key);
return OK;
Expand All @@ -328,13 +334,18 @@ libcdoc::PKCS11Backend::getCertificate(std::vector<uint8_t>& val, int slot, cons
}
std::vector<CK_OBJECT_HANDLE> handles = d->findObjects(d->session, CKO_CERTIFICATE, id, label, nullptr);
LOG_DBG("PKCS11: getCertificate id={}; label={}; found {} certificates", toHex(id), label, handles.size());
if (handles.empty() || (handles.size() != 1)) return CRYPTO_ERROR;
if (handles.empty() || (handles.size() != 1)) {
d->logout();
return CRYPTO_ERROR;
}
CK_OBJECT_HANDLE handle = handles[0];
val = d->attribute(d->session, handle, CKA_VALUE);
if (val.empty()) {
LOG_DBG("PKCS11: getCertificate CKA_VALUE error");
d->logout();
return CRYPTO_ERROR;
}
d->logout();
return OK;
}

Expand All @@ -348,29 +359,36 @@ libcdoc::PKCS11Backend::getPublicKey(std::vector<uint8_t>& val, int slot, const
}
std::vector<CK_OBJECT_HANDLE> handles = d->findObjects(d->session, CKO_PUBLIC_KEY, id, label, nullptr);
LOG_DBG("PKCS11: usePublicKey id={}; label={}; found {} objects", toHex(id), label, handles.size());
if (handles.empty() || (handles.size() != 1)) return CRYPTO_ERROR;
if (handles.empty() || (handles.size() != 1)) {
d->logout();
return CRYPTO_ERROR;
}
CK_OBJECT_HANDLE handle = handles[0];
std::vector<uint8_t> v = d->attribute(d->session, handle, CKA_KEY_TYPE);
if (v.empty()) {
LOG_DBG("PKCS11: getValue CKA_KEY_TYPE error");
d->logout();
return CRYPTO_ERROR;
}
if (*((CK_KEY_TYPE *) v.data()) != CKK_EC)
return libcdoc::NOT_IMPLEMENTED;
v = d->attribute(d->session, handle, CKA_EC_PARAMS);
if (v.empty()) {
LOG_DBG("PKCS11: getValue CKA_EC_PARAMS error");
d->logout();
return CRYPTO_ERROR;
}
std::vector<uint8_t> w = d->attribute(d->session, handle, CKA_EC_POINT);
if (w.empty()) {
LOG_DBG("PKCS11: getValue CKA_EC_POINT error");
d->logout();
return CRYPTO_ERROR;
}
const uint8_t *p = v.data();
EC_GROUP *group = d2i_ECPKParameters(nullptr, &p, v.size());
if (!group) {
LOG_DBG("PKCS11: getValue d2i_ECPKParameters error");
d->logout();
return CRYPTO_ERROR;
}
EC_POINT *pub_key_point = EC_POINT_new(group);
Expand All @@ -381,10 +399,11 @@ libcdoc::PKCS11Backend::getPublicKey(std::vector<uint8_t>& val, int slot, const
EC_KEY_set_public_key(key, pub_key_point);
EVP_PKEY *evp_pkey = EVP_PKEY_new();
EVP_PKEY_assign_EC_KEY(evp_pkey, key);
val = Crypto::toPublicKeyDer(evp_pkey);
val = Crypto::toPublicKeyDerLong(evp_pkey);
EVP_PKEY_free(evp_pkey);
EC_POINT_free(pub_key_point);
EC_GROUP_free(group);
d->logout();
return OK;
}

Expand Down Expand Up @@ -544,15 +563,19 @@ libcdoc::PKCS11Backend::sign(std::vector<uint8_t>& dst, HashAlgorithm algorithm,
data.insert(data.end(), digest.begin(), digest.end());

if(d->f->C_SignInit(d->session, &mech, d->key) != CKR_OK) {
d->logout();
return PKCS11_ERROR;
}
CK_ULONG size = 0;
if(d->f->C_Sign(d->session, CK_BYTE_PTR(data.data()), CK_ULONG(data.size()), nullptr, &size) != CKR_OK) {
d->logout();
return PKCS11_ERROR;
}
dst.resize(int(size));
if(d->f->C_Sign(d->session, CK_BYTE_PTR(data.data()), CK_ULONG(data.size()), CK_BYTE_PTR(dst.data()), &size) != CKR_OK) {
d->logout();
return PKCS11_ERROR;
}
d->logout();
return OK;
}
14 changes: 11 additions & 3 deletions cdoc/PKCS11Backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ struct CDOC_EXPORT PKCS11Backend : public CryptoBackend {
*
* Opens slot, logs in with pin and finds the correct secret key.
* Both key id and label have to match unless either one is empty.
* If the key is found, it is loaded internally for subsequent cryptographic operations.
* If the key is found, it is loaded internally for subsequent cryptographic operations and PKCS11 session remains OPEN.
* If the key is not found, the session closed.
*
* @param slot a PKCS11 slot to use
* @param pin a user pin
* @param id the key id or empty vector
Expand All @@ -91,7 +93,9 @@ struct CDOC_EXPORT PKCS11Backend : public CryptoBackend {
*
* Opens slot, logs in with pin and finds the correct private key.
* Both key id and label have to match unless either one is empty.
* If the key is found, it is loaded internally for subsequent cryptographic operations.
* If the key is found, it is loaded internally for subsequent cryptographic operations and PKCS11 session remains OPEN.
* If the key is not found, the session closed.
*
* @param slot a PKCS11 slot to use
* @param pin a user pin
* @param id the key id
Expand All @@ -105,6 +109,7 @@ struct CDOC_EXPORT PKCS11Backend : public CryptoBackend {
*
* Get a certificate value given slot, label and id.
* Both key id and label have to match unless either one is empty.
*
* @param val a destination container for value
* @param slot the slot to use
* @param pin the pin code or empty if public
Expand All @@ -118,6 +123,7 @@ struct CDOC_EXPORT PKCS11Backend : public CryptoBackend {
*
* Get a public key value given slot, label and id.
* Both key id and label have to match unless either one is empty.
*
* @param val a destination container for value
* @param slot the slot to use
* @param pin the pin code or empty if public
Expand All @@ -133,6 +139,8 @@ struct CDOC_EXPORT PKCS11Backend : public CryptoBackend {
* A method to load the correct private/secret key for given capsule or receiver. The subclass implementation should
* call either useSecretKey or usePrivateKey with proper pin, PKCS11 label and/or id to actually load the key for subsequent
* cryptographic operation.
* On success, the PKCS11 session remains OPEN.
*
* @param idx lock or recipient index (0-based) in CDoc container
* @param priv whether to connect to private or secret key
* @return error code or OK
Expand All @@ -143,7 +151,7 @@ struct CDOC_EXPORT PKCS11Backend : public CryptoBackend {
*
* A subclass should overwrite this to inform the backend about the correct padding.
* @param idx a lock idx
* @return true if PSS padding is sued
* @return true if PSS padding is used
*/
virtual result_t usePSS(int idx) {return true;}

Expand Down
6 changes: 4 additions & 2 deletions cdoc/RcptInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ struct RcptInfo {
// PKCS11/NCrypt data
// NB! PIN is stored in secret
struct PKCS11Info {
long slot = 0;
int64_t slot = -1;
std::vector<uint8_t> key_id;
std::string key_label;
};

enum Type {
// For decryption (use the lock type)
LOCK,

// For encryption
// Certificate from file
CERT,
Expand Down Expand Up @@ -71,6 +70,9 @@ struct RcptInfo {
std::string id;
// Lock index
int lock_idx = -1;

bool isPKCS11() const { return p11.slot >= 0; }
bool needPassword() const { return (type == PASSWORD || type == P11_SYMMETRIC || type == P11_PKI) && !secret.empty() && secret[0] == '?'; }
};

}
Expand Down
Loading
Loading