24 #include "../../log.h"
25 #include "../../Conf.h"
26 #include "../../util/File.h"
27 #include "../cert/X509Cert.h"
60 bool attribute( CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj,
62 std::vector<CK_OBJECT_HANDLE>
findObject( CK_SESSION_HANDLE session, CK_OBJECT_CLASS cls )
const;
65 bool load(
const std::string &driver)
68 return (
h = LoadLibraryW(_driver.c_str())) != 0;
71 void*
resolve(
const char *symbol)
72 {
return h ? (
void*)GetProcAddress(
h, symbol) : 0; }
75 {
if(
h) FreeLibrary(
h);
h = 0; }
77 bool load(
const std::string &driver)
78 {
return (
h = dlopen(driver.c_str(), RTLD_LAZY)); }
81 {
return h ? dlsym(
h, symbol) : 0; }
84 {
if(
h) dlclose(
h);
h = 0; }
98 static const unsigned char sha1[];
107 using namespace digidoc;
110 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
113 { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c };
116 { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 };
119 { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 };
122 { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 };
131 size = attr.ulValueLen;
139 return std::vector<CK_OBJECT_HANDLE>();
142 std::vector<CK_OBJECT_HANDLE> result( count );
143 CK_RV err =
f->
C_FindObjects( session, &result[0], result.size(), &count );
144 result.resize( err ==
CKR_OK ? count : 0 );
180 DEBUG(
"~PKCS11Signer()");
195 d->numberOfSlots = 0;
199 d->f->C_Finalize( 0 );
213 DEBUG(
"PKCS11Signer(driver = '%s')", driver.c_str());
222 CK_C_GetFunctionList l = CK_C_GetFunctionList(d->resolve(
"C_GetFunctionList" ));
225 d->f->C_Initialize( 0 ) !=
CKR_OK )
247 DEBUG(
"PKCS11Signer::getCert()");
250 if(d->sign.certificate.handle())
251 return d->sign.certificate.handle();
260 d->numberOfSlots = 0;
264 if(d->f->C_GetSlotList(
true, 0, &d->numberOfSlots) !=
CKR_OK)
266 d->slots =
new CK_SLOT_ID[d->numberOfSlots];
267 if(d->f->C_GetSlotList(
true, d->slots, &d->numberOfSlots) !=
CKR_OK)
271 CK_SESSION_HANDLE session = 0;
272 std::vector<PKCS11Signer::PKCS11Cert> certificates;
273 std::vector<SignSlot> certSlotMapping;
277 std::vector<CK_OBJECT_HANDLE> objs;
280 d->f->C_CloseSession(session);
282 if(d->f->C_GetTokenInfo(d->slots[
i], &token) !=
CKR_OK ||
287 for(
CK_ULONG j = 0; j < objs.size(); ++j)
290 if(!d->attribute(session, objs[j],
CKA_VALUE, 0, size))
292 std::vector<unsigned char>
value(size, 0);
293 if(!d->attribute(session, objs[j],
CKA_VALUE, &value[0], size))
298 SignSlot signSlot = { x509, d->slots[
i], j };
299 certSlotMapping.push_back(signSlot);
300 certificates.push_back(d->createPKCS11Cert(&token, x509));
304 d->f->C_CloseSession(session);
306 if(certificates.empty())
310 X509Cert selectedCert = selectSigningCertificate(certificates).
cert;
311 if(!selectedCert.
handle())
315 for(std::vector<SignSlot>::const_iterator
i = certSlotMapping.begin();
i != certSlotMapping.end(); ++
i)
317 if(!d->sign.cert &&
i->certificate == selectedCert)
321 if(!d->sign.certificate.handle())
324 return d->sign.certificate.handle();
338 DEBUG(
"sign(digest = {type=%s,digest=%p,length=%d}, signature={signature=%p,length=%d})",
339 OBJ_nid2sn(digest.type), digest.digest, digest.length, signature.signature, signature.length);
342 if(!d->sign.certificate.handle())
347 CK_SESSION_HANDLE session;
348 if(d->f->C_GetTokenInfo(d->sign.slot, &token) !=
CKR_OK ||
356 rv = d->f->C_Login(session,
CKU_USER, 0, 0);
359 std::string pin =
getPin(d->createPKCS11Cert(&token, d->sign.certificate));
368 SignException e( __FILE__, __LINE__,
"PIN acquisition canceled.");
388 std::ostringstream s;
389 s <<
"Failed to login to token '" << token.
label <<
"': " << rv;
397 std::vector<CK_OBJECT_HANDLE> key = d->findObject( session,
CKO_PRIVATE_KEY );
403 if( d->f->C_SignInit( session, &mech, key[d->sign.cert] ) !=
CKR_OK )
406 const unsigned char *sha = 0;
408 switch( digest.type )
417 unsigned char *data =
new unsigned char[size + digest.length];
418 memmove( data, sha, size );
419 memmove( data + size, digest.digest, digest.length );
420 size = size + digest.length;
428 signature.signature =
new unsigned char[signature.length];
429 CK_RV err = d->f->C_Sign(session, data,
CK_ULONG(size), signature.signature,
CK_ULONG_PTR(&signature.length));
450 certificate.
cert = cert;