@ -54,7 +54,7 @@
# if __GNUC__ >= 2
//! Cryptoki Error Message Formatting
/*! If you want to change cryptoki error formatting, just
redefine your own CRYPTOKY_FN_LOG macro before < code > # include
redefine your own CRYPTOKY_FN_LOG macro before < code > \ # include
& lt ; cryptoki . hxx & gt ; < / code > .
# return std::String * /
# define CRYPTOKI_FN_LOG(X) (std::string(X " failed in ") \
@ -64,19 +64,15 @@
# define CRYPTOKI_QUOTE2(X) #X
//! Cryptoki Error Message Formatting
/*! If you want to change cryptoki error formatting, just
redefine your own CRYPTOKY_FN_LOG macro before < code > # include
redefine your own CRYPTOKY_FN_LOG macro before < code > \ # include
& lt ; cryptoki . hxx & gt ; < / code > .
# return std::String * /
@ return string * /
# define CRYPTOKI_FN_LOG(X) X " failed in \
" __FILE__ " : " CRYPTOKI_QUOTE(__LINE__)
# endif
# endif
//@}
namespace pcsc {
std : : string version ( ) ;
}
//! @ref gcryptoki @copydoc gcryptoki
namespace cryptoki {
@ -261,7 +257,7 @@ namespace cryptoki {
std : : string res ( indent , ' ' ) ;
switch ( type ) {
case CKA_CLASS :
switch ( * ( ( CK_OBJECT_CLASS * ) & value [ 0 ] ) ) {
switch ( * ( ( const CK_OBJECT_CLASS * ) & value [ 0 ] ) ) {
case CKO_DATA : return res + " DATA " ;
case CKO_CERTIFICATE : return res + " CERTIFICATE " ;
case CKO_PUBLIC_KEY : return res + " PUBLIC_KEY " ;
@ -279,7 +275,7 @@ namespace cryptoki {
/** To use this method, you must know what type the attribute
represents . */
template < typename TYPE > Attribute & from ( const TYPE & v ) {
value = std : : string ( ( char * ) & v , sizeof ( TYPE ) ) ;
value = std : : string ( ( const char * ) & v , sizeof ( TYPE ) ) ;
return * this ;
}
/// Convert to a given type.
@ -1107,9 +1103,9 @@ namespace cryptoki {
shared library . Normally you need only one instance .
@ param library name of the shared library that supports pkcs # 11
@ param exc wether exceptions should be thrown */
Library ( const std : : string & library , bool exc = true ) :
_init ( new Init ( library , exc ) ) {
@ param exceptions wh ether exceptions should be thrown */
Library ( const std : : string & library , bool exceptions = true ) :
_init ( new Init ( library , exceptions ) ) {
CRYPTOLOG ( " log " ) ;
}
@ -1545,7 +1541,8 @@ namespace cryptoki {
public :
//! Opens a new session.
/*! @param slot slot to open a session on */
/*! @param slot slot to open a session on
@ param rw whether session is read / write or read only */
Session ( const Slot & slot , bool rw = false ) :
_slot ( slot ) , _session ( 0 ) , _res ( CKR_OK ) {
CRYPTOLOG ( " log " ) ;
@ -1553,8 +1550,7 @@ namespace cryptoki {
//! @todo pass parameter
}
//! Opens a new session.
/*! @param slot slot to open a session on */
//! Copy session.
Session ( const Session & o ) :
_slot ( o . _slot ) , _session ( o . _session ) , _res ( CKR_OK ) {
CRYPTOLOG ( " log " ) ;
@ -1822,6 +1818,26 @@ namespace cryptoki {
CRYPTOKI_FN_LOG ( " C_GetSessionInfo " ) ) ;
return info ;
}
/*! @todo Not implemented:
@ code
bool seedrandom ( ) {
CRYPTOLOG ( " log " ) ;
//! calls @c C_SeedRandom
return check ( _slot . library ( ) - > C_SeedRandom ( _session , CK_BYTE_PTR , CK_ULONG ) ,
CRYPTOKI_FN_LOG ( " C_SeedRandom " ) ) ;
}
@ endcode */
/*! @todo Not implemented:
@ code
bool setpin ( ) {
CRYPTOLOG ( " log " ) ;
//! calls @c C_SetPIN
return check ( _slot . library ( ) - > C_SetPIN ( _session , CK_CHAR_PTR , CK_ULONG , CK_CHAR_PTR , CK_ULONG ) ,
CRYPTOKI_FN_LOG ( " C_SetPIN " ) ) ;
}
@ endcode */
/*! @todo Not implemented:
@ code
@ -1833,6 +1849,13 @@ namespace cryptoki {
}
@ endcode */
//@}
/** @name login with pin
Unlock access with pin ( login ) and unlock after use ( logout ) . */
//@{
private :
class Login {
@ -1846,8 +1869,8 @@ namespace cryptoki {
//! calls @c C_Login
_session . check ( _session . _slot . library ( ) - > C_Login
( _session . _session , userType ,
( CK_CHAR * ) pin . c_str ( ) ,
pin . size ( ) ) ,
const_cast < CK_CHAR * > ( ( const CK_CHAR * ) pin . c_str ( ) ) ,
( int ) pin . size ( ) ) ,
CRYPTOKI_FN_LOG ( " C_Login " ) ) ;
}
@ -1874,37 +1897,26 @@ namespace cryptoki {
public :
void login ( const std : : string & pin , CK_USER_TYPE userType = CKU_USER ) {
/// Login to card
/** @param pin to unlock card
@ param userType user type */
void login ( const std : : string & pin ,
CK_USER_TYPE userType = CKU_USER ) {
CRYPTOLOG ( " log " ) ;
_login = new Login ( * this , pin , userType ) ;
}
/// Logout from card
/** Undo the last login. */
void logout ( ) {
CRYPTOLOG ( " log " ) ;
_login . reset ( ) ;
}
mrw : : Shared < Login > _login ;
/*! @todo Not implemented:
@ code
bool seedrandom ( ) {
CRYPTOLOG ( " log " ) ;
//! calls @c C_SeedRandom
return check ( _slot . library ( ) - > C_SeedRandom ( _session , CK_BYTE_PTR , CK_ULONG ) ,
CRYPTOKI_FN_LOG ( " C_SeedRandom " ) ) ;
}
@ endcode */
/*! @todo Not implemented:
@ code
bool setpin ( ) {
CRYPTOLOG ( " log " ) ;
//! calls @c C_SetPIN
return check ( _slot . library ( ) - > C_SetPIN ( _session , CK_CHAR_PTR , CK_ULONG , CK_CHAR_PTR , CK_ULONG ) ,
CRYPTOKI_FN_LOG ( " C_SetPIN " ) ) ;
}
@ endcode */
//@}
} ;
class Object {
@ -1985,6 +1997,218 @@ namespace cryptoki {
//! @todo don't call verifyfinal()?
}
bool destroy ( ) {
CRYPTOLOG ( " log " ) ;
//! calls @c C_DestroyObject
return check ( _session . _slot . library ( ) - > C_DestroyObject
( _session . _session , _object ) ,
CRYPTOKI_FN_LOG ( " C_DestroyObject " ) ) ;
}
//! Get a Single Attribute
Attribute operator [ ] ( CK_ATTRIBUTE_TYPE a ) {
CRYPTOLOG ( " log " ) ;
return attribute ( a ) ;
}
//! Get a Single Attribute
Attribute attribute ( CK_ATTRIBUTE_TYPE a ) {
CRYPTOLOG ( " log " ) ;
Attribute res ;
CK_ATTRIBUTE attr ( CK_ATTRIBUTE { a , 0 , 0 } ) ;
//! calls @c C_GetAttributeValue
if ( ! check ( _session . _slot . library ( ) - > C_GetAttributeValue
( _session . _session , _object , & attr , 1 ) ,
CRYPTOKI_FN_LOG ( " C_GetAttributeValue " ) )
| | ! ( long ) attr . ulValueLen > 0l )
//! Without exception handling, size and type must be checked too.
return res ;
try {
attr . pValue = malloc ( attr . ulValueLen ) ;
attr . pValue = memset ( attr . pValue , 0 , attr . ulValueLen ) ;
if ( check ( _session . _slot . library ( ) - > C_GetAttributeValue
( _session . _session , _object , & attr , 1 ) ,
CRYPTOKI_FN_LOG ( " C_GetAttributeValue " ) ) )
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
Cryptoki . From the Specs : « In the special case
of an attribute whose value is an array of
attributes , for example CKA_WRAP_TEMPLATE , where
it is passed in with pValue not NULL , then if
the pValue of elements within the array is
NULL_PTR then the ulValueLen of elements within
the array will be set to the required length . If
the pValue of elements within the array is not
NULL_PTR , then the ulValueLen element of
attributes within the array must reflect the
space that the corresponding pValue points to ,
and pValue is filled in if there is sufficient
room . Therefore it is important to initialize
the contents of a buffer before calling
C_GetAttributeValue to get such an array
value . If any ulValueLen within the array isn ' t
large enough , it will be set to - 1 and the
function will return CKR_BUFFER_TOO_SMALL , as it
does if an attribute in the pTemplate argument
has ulValueLen too small . Note that any
attribute whose value is an array of attributes
is identifiable by virtue of the attribute type
having the CKF_ARRAY_ATTRIBUTE bit set . » */
res = Attribute ( attr ) ;
else
free ( attr . pValue ) ;
} catch ( . . . ) {
free ( attr . pValue ) ;
throw ;
}
return res ;
}
//! Get a List of Attributes.
/*! If @c attrs is empty, all available attributes are
returned . Attributes that cannot be accessed or that are not
available in this Object won ' t be in the result map . There
is no exception in this case . */
AttributeMap attributes ( AttributeTypeList attrs
= AttributeTypeList ( ) ) {
CRYPTOLOG ( " log " ) ;
AttributeMap res ;
//! Gets all attributes, if @c attrs is empty
if ( attrs . empty ( ) ) {
attrs . push_back ( CKA_CLASS ) ;
attrs . push_back ( CKA_TOKEN ) ;
attrs . push_back ( CKA_PRIVATE ) ;
attrs . push_back ( CKA_LABEL ) ;
attrs . push_back ( CKA_APPLICATION ) ;
attrs . push_back ( CKA_VALUE ) ;
attrs . push_back ( CKA_OBJECT_ID ) ;
attrs . push_back ( CKA_CERTIFICATE_TYPE ) ;
attrs . push_back ( CKA_ISSUER ) ;
attrs . push_back ( CKA_SERIAL_NUMBER ) ;
attrs . push_back ( CKA_AC_ISSUER ) ;
attrs . push_back ( CKA_OWNER ) ;
attrs . push_back ( CKA_ATTR_TYPES ) ;
attrs . push_back ( CKA_TRUSTED ) ;
attrs . push_back ( CKA_KEY_TYPE ) ;
attrs . push_back ( CKA_SUBJECT ) ;
attrs . push_back ( CKA_ID ) ;
attrs . push_back ( CKA_SENSITIVE ) ;
attrs . push_back ( CKA_ENCRYPT ) ;
attrs . push_back ( CKA_DECRYPT ) ;
attrs . push_back ( CKA_WRAP ) ;
attrs . push_back ( CKA_UNWRAP ) ;
attrs . push_back ( CKA_SIGN ) ;
attrs . push_back ( CKA_SIGN_RECOVER ) ;
attrs . push_back ( CKA_VERIFY ) ;
attrs . push_back ( CKA_VERIFY_RECOVER ) ;
attrs . push_back ( CKA_DERIVE ) ;
attrs . push_back ( CKA_START_DATE ) ;
attrs . push_back ( CKA_END_DATE ) ;
attrs . push_back ( CKA_MODULUS ) ;
attrs . push_back ( CKA_MODULUS_BITS ) ;
attrs . push_back ( CKA_PUBLIC_EXPONENT ) ;
attrs . push_back ( CKA_PRIVATE_EXPONENT ) ;
attrs . push_back ( CKA_PRIME_1 ) ;
attrs . push_back ( CKA_PRIME_2 ) ;
attrs . push_back ( CKA_EXPONENT_1 ) ;
attrs . push_back ( CKA_EXPONENT_2 ) ;
attrs . push_back ( CKA_COEFFICIENT ) ;
attrs . push_back ( CKA_PRIME ) ;
attrs . push_back ( CKA_SUBPRIME ) ;
attrs . push_back ( CKA_BASE ) ;
attrs . push_back ( CKA_PRIME_BITS ) ;
//attrs.push_back(CKA_SUBPRIME_BITS);
attrs . push_back ( CKA_VALUE_BITS ) ;
attrs . push_back ( CKA_VALUE_LEN ) ;
attrs . push_back ( CKA_EXTRACTABLE ) ;
attrs . push_back ( CKA_LOCAL ) ;
attrs . push_back ( CKA_NEVER_EXTRACTABLE ) ;
attrs . push_back ( CKA_ALWAYS_SENSITIVE ) ;
attrs . push_back ( CKA_KEY_GEN_MECHANISM ) ;
attrs . push_back ( CKA_MODIFIABLE ) ;
attrs . push_back ( CKA_ECDSA_PARAMS ) ;
attrs . push_back ( CKA_EC_PARAMS ) ;
attrs . push_back ( CKA_EC_POINT ) ;
attrs . push_back ( CKA_SECONDARY_AUTH ) ;
attrs . push_back ( CKA_AUTH_PIN_FLAGS ) ;
attrs . push_back ( CKA_HW_FEATURE_TYPE ) ;
attrs . push_back ( CKA_RESET_ON_INIT ) ;
attrs . push_back ( CKA_HAS_RESET ) ;
attrs . push_back ( CKA_VENDOR_DEFINED ) ;
//attrs.push_back(CKA_IBM_OPAQUE);
}
CK_ATTRIBUTE attr ;
for ( AttributeTypeList : : const_iterator it ( attrs . begin ( ) ) ;
it ! = attrs . end ( ) ; + + it ) {
attr = CK_ATTRIBUTE { * it , 0 , 0 } ;
try {
//! calls @c C_GetAttributeValue
if ( _session . _slot . library ( ) - > C_GetAttributeValue
( _session . _session , _object , & attr , 1 )
= = CKR_ATTRIBUTE_TYPE_INVALID
| | _res = = CKR_ATTRIBUTE_SENSITIVE ) {
continue ; //! Ignores unsupported Attributes.
} else {
check ( _res , CRYPTOKI_FN_LOG ( " C_GetAttributeValue " ) ) ;
if ( ( long ) attr . ulValueLen > 0l ) {
attr . pValue = malloc ( attr . ulValueLen ) ;
attr . pValue = memset ( attr . pValue , 0 , attr . ulValueLen ) ;
if ( check ( _session . _slot . library ( ) - > C_GetAttributeValue
( _session . _session , _object , & attr , 1 ) ,
CRYPTOKI_FN_LOG ( " C_GetAttributeValue " ) ) )
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
Cryptoki . From the Specs : « In the special
case of an attribute whose value is an
array of attributes , for example
CKA_WRAP_TEMPLATE , where it is passed in
with pValue not NULL , then if the pValue
of elements within the array is NULL_PTR
then the ulValueLen of elements within the
array will be set to the required
length . If the pValue of elements within
the array is not NULL_PTR , then the
ulValueLen element of attributes within
the array must reflect the space that the
corresponding pValue points to , and pValue
is filled in if there is sufficient
room . Therefore it is important to
initialize the contents of a buffer before
calling C_GetAttributeValue to get such an
array value . If any ulValueLen within the
array isn ' t large enough , it will be set
to - 1 and the function will return
CKR_BUFFER_TOO_SMALL , as it does if an
attribute in the pTemplate argument has
ulValueLen too small . Note that any
attribute whose value is an array of
attributes is identifiable by virtue of
the attribute type having the
CKF_ARRAY_ATTRIBUTE bit set . » */
res . insert ( std : : make_pair ( attr . type , Attribute ( attr ) ) ) ;
else
free ( attr . pValue ) ;
} else if ( * it = = CKA_MODULUS & & attr . ulValueLen = = 0 ) {
/*! @bug This is a bug in opensc-pkcs11.so: If
@ c CKA_MODULUS has a size of 0 bytes , the
following query to @ c CKA_MODULUS_BITS ends
in a segmentation fault .
@ note @ c CKA_MODULUS @ b must immediately be
followed by @ c CKA_MODULUS_BITS in the
attribute list , because if the size of @ c
CKA_MODULUS is 0 Bytes , the following
attribute query is skipped as a work around
to this bug . */
if ( + + it = = attrs . end ( ) ) break ;
}
}
} catch ( . . . ) {
free ( attr . pValue ) ;
throw ;
}
}
return res ;
}
//@}
/*! @name C Like Error Handling
@ -2046,13 +2270,15 @@ namespace cryptoki {
//! calls @c C_Decrypt
check ( _session . _slot . library ( ) - > C_Decrypt
( _session . _session ,
( unsigned char * ) & in [ 0 ] , in . size ( ) , 0 , & size ) ,
const_cast < CK_BYTE_PTR > ( ( const unsigned char * ) & in [ 0 ] ) ,
in . size ( ) , 0 , & size ) ,
CRYPTOKI_FN_LOG ( " C_Decrypt " ) ) ;
CRYPTOLOG ( " maximum size is " < < size < < " Bytes " ) ;
res . resize ( size , 0 ) ;
check ( _session . _slot . library ( ) - > C_Decrypt
( _session . _session ,
( unsigned char * ) & in [ 0 ] , in . size ( ) ,
const_cast < CK_BYTE_PTR > ( ( const unsigned char * ) & in [ 0 ] ) ,
in . size ( ) ,
( unsigned char * ) & res [ 0 ] , & size ) ,
CRYPTOKI_FN_LOG ( " C_Decrypt " ) ) ;
CRYPTOLOG ( " exact size is " < < size < < " Bytes " ) ;
@ -2068,7 +2294,7 @@ namespace cryptoki {
//! calls @c C_DecryptDigestUpdate
check ( _session . _slot . library ( ) - > C_DecryptDigestUpdate
( _session . _session ,
( unsigned char * ) & in [ 0 ] , in . size ( ) ,
const_cast < CK_BYTE_PTR > ( ( const unsigned char * ) & in [ 0 ] ) , in . size ( ) ,
( unsigned char * ) & res [ 0 ] , & size ) ,
CRYPTOKI_FN_LOG ( " C_DecryptDigestUpdate " ) ) ;
res . resize ( size ) ;
@ -2230,7 +2456,6 @@ namespace cryptoki {
CRYPTOKI_FN_LOG ( " C_VerifyUpdate " ) ) ;
}
@ endcode */
//@}
/*! @todo Not implemented:
@ code
@ -2243,15 +2468,6 @@ namespace cryptoki {
}
@ endcode */
bool destroy ( ) {
CRYPTOLOG ( " log " ) ;
//! calls @c C_DestroyObject
return check ( _session . _slot . library ( ) - > C_DestroyObject
( _session . _session , _object ) ,
CRYPTOKI_FN_LOG ( " C_DestroyObject " ) ) ;
}
/*! @todo Not implemented:
@ code
bool digestkey ( ) {
@ -2265,7 +2481,8 @@ namespace cryptoki {
bool encryptinit ( CK_MECHANISM_TYPE type , const std : : string & param ) {
CRYPTOLOG ( " log " ) ;
CK_MECHANISM mech = {
type , param . size ( ) ? ( void * ) & param [ 0 ] : 0 , param . size ( )
type , param . size ( ) ? const_cast < CK_VOID_PTR > ( ( const void * ) & param [ 0 ] ) : 0 ,
param . size ( )
} ;
CRYPTOLOG ( " encryptinit: type= " < < type < < " ; mech=( " < < mech . mechanism
< < " , " < < mech . pParameter < < " , " < < mech . ulParameterLen < < ' ) ' ) ;
@ -2283,13 +2500,14 @@ namespace cryptoki {
//! calls @c C_Encrypt
check ( _session . _slot . library ( ) - > C_Encrypt
( _session . _session ,
( unsigned char * ) & in [ 0 ] , in . size ( ) , 0 , & size ) ,
const_cast < CK_BYTE_PTR > ( ( const unsigned char * ) & in [ 0 ] ) ,
in . size ( ) , 0 , & size ) ,
CRYPTOKI_FN_LOG ( " C_Decrypt " ) ) ;
CRYPTOLOG ( " maximum size is " < < size < < " Bytes " ) ;
res . resize ( size , 0 ) ;
check ( _session . _slot . library ( ) - > C_Encrypt
( _session . _session ,
( unsigned char * ) & in [ 0 ] , in . size ( ) ,
const_cast < CK_BYTE_PTR > ( ( const unsigned char * ) & in [ 0 ] ) , in . size ( ) ,
( unsigned char * ) & res [ 0 ] , & size ) ,
CRYPTOKI_FN_LOG ( " C_Encrypt " ) ) ;
res . resize ( size ) ;
@ -2345,211 +2563,6 @@ namespace cryptoki {
}
@ endcode */
//! Get a Single Attribute
Attribute operator [ ] ( CK_ATTRIBUTE_TYPE a ) {
CRYPTOLOG ( " log " ) ;
return attribute ( a ) ;
}
//! Get a Single Attribute
Attribute attribute ( CK_ATTRIBUTE_TYPE a ) {
CRYPTOLOG ( " log " ) ;
Attribute res ;
CK_ATTRIBUTE attr ( ( CK_ATTRIBUTE ) { a , 0 , 0 } ) ;
//! calls @c C_GetAttributeValue
if ( ! check ( _session . _slot . library ( ) - > C_GetAttributeValue
( _session . _session , _object , & attr , 1 ) ,
CRYPTOKI_FN_LOG ( " C_GetAttributeValue " ) )
| | ! ( long ) attr . ulValueLen > 0l )
//! Without exception handling, size and type must be checked too.
return res ;
try {
attr . pValue = malloc ( attr . ulValueLen ) ;
attr . pValue = memset ( attr . pValue , 0 , attr . ulValueLen ) ;
if ( check ( _session . _slot . library ( ) - > C_GetAttributeValue
( _session . _session , _object , & attr , 1 ) ,
CRYPTOKI_FN_LOG ( " C_GetAttributeValue " ) ) )
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
Cryptoki . From the Specs : « In the special case
of an attribute whose value is an array of
attributes , for example CKA_WRAP_TEMPLATE , where
it is passed in with pValue not NULL , then if
the pValue of elements within the array is
NULL_PTR then the ulValueLen of elements within
the array will be set to the required length . If
the pValue of elements within the array is not
NULL_PTR , then the ulValueLen element of
attributes within the array must reflect the
space that the corresponding pValue points to ,
and pValue is filled in if there is sufficient
room . Therefore it is important to initialize
the contents of a buffer before calling
C_GetAttributeValue to get such an array
value . If any ulValueLen within the array isn ' t
large enough , it will be set to - 1 and the
function will return CKR_BUFFER_TOO_SMALL , as it
does if an attribute in the pTemplate argument
has ulValueLen too small . Note that any
attribute whose value is an array of attributes
is identifiable by virtue of the attribute type
having the CKF_ARRAY_ATTRIBUTE bit set . » */
res = Attribute ( attr ) ;
else
free ( attr . pValue ) ;
} catch ( . . . ) {
free ( attr . pValue ) ;
throw ;
}
return res ;
}
//! Get a List of Attributes.
/*! If @c attrs is empty, all available attributes are
returned . Attributes that cannot be accessed or that are not
available in this Object won ' t be in the result map . There
is no exception in this case . */
AttributeMap attributes ( AttributeTypeList attrs
= AttributeTypeList ( ) ) {
CRYPTOLOG ( " log " ) ;
AttributeMap res ;
//! Gets all attributes, if @c attrs is empty
if ( attrs . empty ( ) ) {
attrs . push_back ( CKA_CLASS ) ;
attrs . push_back ( CKA_TOKEN ) ;
attrs . push_back ( CKA_PRIVATE ) ;
attrs . push_back ( CKA_LABEL ) ;
attrs . push_back ( CKA_APPLICATION ) ;
attrs . push_back ( CKA_VALUE ) ;
attrs . push_back ( CKA_OBJECT_ID ) ;
attrs . push_back ( CKA_CERTIFICATE_TYPE ) ;
attrs . push_back ( CKA_ISSUER ) ;
attrs . push_back ( CKA_SERIAL_NUMBER ) ;
attrs . push_back ( CKA_AC_ISSUER ) ;
attrs . push_back ( CKA_OWNER ) ;
attrs . push_back ( CKA_ATTR_TYPES ) ;
attrs . push_back ( CKA_TRUSTED ) ;
attrs . push_back ( CKA_KEY_TYPE ) ;
attrs . push_back ( CKA_SUBJECT ) ;
attrs . push_back ( CKA_ID ) ;
attrs . push_back ( CKA_SENSITIVE ) ;
attrs . push_back ( CKA_ENCRYPT ) ;
attrs . push_back ( CKA_DECRYPT ) ;
attrs . push_back ( CKA_WRAP ) ;
attrs . push_back ( CKA_UNWRAP ) ;
attrs . push_back ( CKA_SIGN ) ;
attrs . push_back ( CKA_SIGN_RECOVER ) ;
attrs . push_back ( CKA_VERIFY ) ;
attrs . push_back ( CKA_VERIFY_RECOVER ) ;
attrs . push_back ( CKA_DERIVE ) ;
attrs . push_back ( CKA_START_DATE ) ;
attrs . push_back ( CKA_END_DATE ) ;
attrs . push_back ( CKA_MODULUS ) ;
attrs . push_back ( CKA_MODULUS_BITS ) ;
attrs . push_back ( CKA_PUBLIC_EXPONENT ) ;
attrs . push_back ( CKA_PRIVATE_EXPONENT ) ;
attrs . push_back ( CKA_PRIME_1 ) ;
attrs . push_back ( CKA_PRIME_2 ) ;
attrs . push_back ( CKA_EXPONENT_1 ) ;
attrs . push_back ( CKA_EXPONENT_2 ) ;
attrs . push_back ( CKA_COEFFICIENT ) ;
attrs . push_back ( CKA_PRIME ) ;
attrs . push_back ( CKA_SUBPRIME ) ;
attrs . push_back ( CKA_BASE ) ;
attrs . push_back ( CKA_PRIME_BITS ) ;
//attrs.push_back(CKA_SUBPRIME_BITS);
attrs . push_back ( CKA_VALUE_BITS ) ;
attrs . push_back ( CKA_VALUE_LEN ) ;
attrs . push_back ( CKA_EXTRACTABLE ) ;
attrs . push_back ( CKA_LOCAL ) ;
attrs . push_back ( CKA_NEVER_EXTRACTABLE ) ;
attrs . push_back ( CKA_ALWAYS_SENSITIVE ) ;
attrs . push_back ( CKA_KEY_GEN_MECHANISM ) ;
attrs . push_back ( CKA_MODIFIABLE ) ;
attrs . push_back ( CKA_ECDSA_PARAMS ) ;
attrs . push_back ( CKA_EC_PARAMS ) ;
attrs . push_back ( CKA_EC_POINT ) ;
attrs . push_back ( CKA_SECONDARY_AUTH ) ;
attrs . push_back ( CKA_AUTH_PIN_FLAGS ) ;
attrs . push_back ( CKA_HW_FEATURE_TYPE ) ;
attrs . push_back ( CKA_RESET_ON_INIT ) ;
attrs . push_back ( CKA_HAS_RESET ) ;
attrs . push_back ( CKA_VENDOR_DEFINED ) ;
//attrs.push_back(CKA_IBM_OPAQUE);
}
CK_ATTRIBUTE attr ;
for ( AttributeTypeList : : const_iterator it ( attrs . begin ( ) ) ;
it ! = attrs . end ( ) ; + + it ) {
attr = ( CK_ATTRIBUTE ) { * it , 0 , 0 } ;
try {
//! calls @c C_GetAttributeValue
if ( _session . _slot . library ( ) - > C_GetAttributeValue
( _session . _session , _object , & attr , 1 )
= = CKR_ATTRIBUTE_TYPE_INVALID
| | _res = = CKR_ATTRIBUTE_SENSITIVE ) {
continue ; //! Ignores unsupported Attributes.
} else {
check ( _res , CRYPTOKI_FN_LOG ( " C_GetAttributeValue " ) ) ;
if ( ( long ) attr . ulValueLen > 0l ) {
attr . pValue = malloc ( attr . ulValueLen ) ;
attr . pValue = memset ( attr . pValue , 0 , attr . ulValueLen ) ;
if ( check ( _session . _slot . library ( ) - > C_GetAttributeValue
( _session . _session , _object , & attr , 1 ) ,
CRYPTOKI_FN_LOG ( " C_GetAttributeValue " ) ) )
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
Cryptoki . From the Specs : « In the special
case of an attribute whose value is an
array of attributes , for example
CKA_WRAP_TEMPLATE , where it is passed in
with pValue not NULL , then if the pValue
of elements within the array is NULL_PTR
then the ulValueLen of elements within the
array will be set to the required
length . If the pValue of elements within
the array is not NULL_PTR , then the
ulValueLen element of attributes within
the array must reflect the space that the
corresponding pValue points to , and pValue
is filled in if there is sufficient
room . Therefore it is important to
initialize the contents of a buffer before
calling C_GetAttributeValue to get such an
array value . If any ulValueLen within the
array isn ' t large enough , it will be set
to - 1 and the function will return
CKR_BUFFER_TOO_SMALL , as it does if an
attribute in the pTemplate argument has
ulValueLen too small . Note that any
attribute whose value is an array of
attributes is identifiable by virtue of
the attribute type having the
CKF_ARRAY_ATTRIBUTE bit set . » */
res . insert ( std : : make_pair ( attr . type , Attribute ( attr ) ) ) ;
else
free ( attr . pValue ) ;
} else if ( * it = = CKA_MODULUS & & attr . ulValueLen = = 0 ) {
/*! @bug This is a bug in opensc-pkcs11.so: If
@ c CKA_MODULUS has a size of 0 bytes , the
following query to @ c CKA_MODULUS_BITS ends
in a segmentation fault .
@ note @ c CKA_MODULUS @ b must immediately be
followed by @ c CKA_MODULUS_BITS in the
attribute list , because if the size of @ c
CKA_MODULUS is 0 Bytes , the following
attribute query is skipped as a work around
to this bug . */
if ( + + it = = attrs . end ( ) ) break ;
}
}
} catch ( . . . ) {
free ( attr . pValue ) ;
throw ;
}
}
return res ;
}
/*! @todo Not implemented:
@ code
bool getobjectsize ( ) {
@ -2660,8 +2673,9 @@ namespace cryptoki {
}
//! @groupadd cryptokitypes
//! @addto group cryptokitypes
//@{
/// Append a cryptoki::Attribute to a cryptoki::AttributeList.
inline cryptoki : : AttributeList & operator < < ( cryptoki : : AttributeList & list ,
const cryptoki : : Attribute & attr ) {
@ -2669,6 +2683,7 @@ inline cryptoki::AttributeList& operator<<(cryptoki::AttributeList& list,
list . push_back ( attr ) ;
return list ;
}
/// Append a cryptoki::Attribute to a new copy of a cryptoki::AttributeList.
inline cryptoki : : AttributeList operator < < ( const cryptoki : : AttributeList & list ,
const cryptoki : : Attribute & attr ) {
@ -2677,6 +2692,7 @@ inline cryptoki::AttributeList operator<<(const cryptoki::AttributeList& list,
res . push_back ( attr ) ;
return res ;
}
//@}
# endif