2121 */
2222
2323#include " Pkcs11ElectronicID.hpp"
24+ #include " ../scope.hpp"
2425
26+ #include < algorithm>
2527#include < map>
2628
2729#ifdef _WIN32
@@ -222,56 +224,53 @@ Pkcs11ElectronicID::Pkcs11ElectronicID(ElectronicID::Type type) :
222224{
223225 REQUIRE_NON_NULL (manager)
224226
225- bool seenAuthToken = false ;
226- bool seenSigningToken = false ;
227-
228227 for (const auto & token : manager->tokens ()) {
229228 const auto certType = certificateType (token.cert );
230229 if (certType.isAuthentication ()) {
231230 authToken = token;
232- seenAuthToken = true ;
233231 } else if (certType.isSigning ()) {
234232 signingToken = token;
235- seenSigningToken = true ;
236233 }
237234 }
238- if (!(seenAuthToken && seenSigningToken)) {
239- THROW (SmartCardChangeRequiredError, " Either authentication or signing token is missing" );
240- }
241235}
242236
243237pcsc_cpp::byte_vector Pkcs11ElectronicID::getCertificate (const CertificateType type) const
244238{
245- return type. isAuthentication () ? authToken. cert : signingToken .cert ;
239+ return token (type) .cert ;
246240}
247241
248242JsonWebSignatureAlgorithm Pkcs11ElectronicID::authSignatureAlgorithm () const
249243{
250- return getAuthAlgorithmFromCert (authToken .cert );
244+ return getAuthAlgorithmFromCert (token (CertificateType::AUTHENTICATION) .cert );
251245}
252246
253247ElectronicID::PinMinMaxLength Pkcs11ElectronicID::authPinMinMaxLength () const
254248{
255- return {authToken.minPinLen , authToken.maxPinLen };
249+ const auto & t = token (CertificateType::AUTHENTICATION);
250+ return {t.minPinLen , t.maxPinLen };
256251}
257252
258253ElectronicID::PinInfo Pkcs11ElectronicID::authPinInfo () const
259254{
260- return {authToken .retry , module .retryMax , true };
255+ return {token (CertificateType::AUTHENTICATION) .retry , module .retryMax , true };
261256}
262257
263258pcsc_cpp::byte_vector Pkcs11ElectronicID::signWithAuthKey (byte_vector&& pin,
264259 const byte_vector& hash) const
265260{
261+ auto clearPin = stdext::make_scope_exit ([&pin] {
262+ std::fill (pin.begin (), pin.end (), byte_type (0 ));
263+ pin.clear ();
264+ });
266265 REQUIRE_NON_NULL (manager)
267266
268267 try {
269268 validateAuthHashLength (authSignatureAlgorithm (), name (), hash);
270269
271- const auto signature =
272- manager-> sign (authToken, hash, authSignatureAlgorithm ().hashAlgorithm (),
273- module .providesExternalPinDialog ,
274- reinterpret_cast <const char *>(pin.data ()), pin.size ());
270+ const auto signature = manager-> sign ( token (CertificateType::AUTHENTICATION), hash,
271+ authSignatureAlgorithm ().hashAlgorithm (),
272+ module .providesExternalPinDialog ,
273+ reinterpret_cast <const char *>(pin.data ()), pin.size ());
275274 return signature.first ;
276275 } catch (const VerifyPinFailed& e) {
277276 // Catch and rethrow the VerifyPinFailed error with -1 to inform the caller of the special
@@ -287,37 +286,42 @@ pcsc_cpp::byte_vector Pkcs11ElectronicID::signWithAuthKey(byte_vector&& pin,
287286
288287const std::set<SignatureAlgorithm>& Pkcs11ElectronicID::supportedSigningAlgorithms () const
289288{
290- return getSignAlgorithmFromCert (signingToken .cert );
289+ return getSignAlgorithmFromCert (token (CertificateType::SIGNING) .cert );
291290}
292291
293292ElectronicID::PinMinMaxLength Pkcs11ElectronicID::signingPinMinMaxLength () const
294293{
295- return {signingToken.minPinLen , signingToken.maxPinLen };
294+ const auto & t = token (CertificateType::SIGNING);
295+ return {t.minPinLen , t.maxPinLen };
296296}
297297
298298ElectronicID::PinInfo Pkcs11ElectronicID::signingPinInfo () const
299299{
300- return {signingToken .retry , module .retryMax , true };
300+ return {token (CertificateType::SIGNING) .retry , module .retryMax , true };
301301}
302302
303303ElectronicID::Signature Pkcs11ElectronicID::signWithSigningKey (byte_vector&& pin,
304304 const byte_vector& hash,
305305 const HashAlgorithm hashAlgo) const
306306{
307+ auto clearPin = stdext::make_scope_exit ([&pin] {
308+ std::fill (pin.begin (), pin.end (), byte_type (0 ));
309+ pin.clear ();
310+ });
307311 REQUIRE_NON_NULL (manager)
308312
309313 try {
310314 validateSigningHash (*this , hashAlgo, hash);
311315
312316 // TODO: add step for supported algo detection before sign(), see if () below.
313- auto signature =
314- manager-> sign (signingToken, hash, hashAlgo, module .providesExternalPinDialog ,
315- reinterpret_cast <const char *>(pin.data ()), pin.size ());
317+ auto signature = manager-> sign ( token (CertificateType::SIGNING), hash, hashAlgo,
318+ module .providesExternalPinDialog ,
319+ reinterpret_cast <const char *>(pin.data ()), pin.size ());
316320
317- if (!supportedSigningAlgorithms ().count (signature.second )) {
321+ if (!supportedSigningAlgorithms ().contains (signature.second )) {
318322 THROW (SmartCardChangeRequiredError,
319323 " Signature algorithm " + std::string (signature.second ) + " is not supported by "
320- + name ());
324+ + std::string ( name () ));
321325 }
322326
323327 return signature;
@@ -330,6 +334,20 @@ ElectronicID::Signature Pkcs11ElectronicID::signWithSigningKey(byte_vector&& pin
330334 }
331335}
332336
337+ const PKCS11CardManager::Token& Pkcs11ElectronicID::token (const CertificateType type) const
338+ {
339+ if (type.isAuthentication ()) {
340+ if (authToken.cert .empty ()) {
341+ THROW (SmartCardChangeRequiredError, " Authentication token is missing" );
342+ }
343+ return authToken;
344+ }
345+ if (signingToken.cert .empty ()) {
346+ THROW (SmartCardChangeRequiredError, " Signing token is missing" );
347+ }
348+ return signingToken;
349+ }
350+
333351void Pkcs11ElectronicID::release () const
334352{
335353 manager.reset ();
0 commit comments