Download the Cryptlib manual

Transcript
Enveloping with Multiple Attributes
77
Processing Multiple De-enveloping Attributes
The attributes required for de-enveloping are managed through the use of an attribute
cursor as described in “Attribute Lists and Attribute Groups” on page 40. You can
use the attribute cursor to determine which attribute is required for the de-enveloping
process. Once you’re iterating through the attributes, all that’s left to do is to plug in
the appropriate handler routines to manage each attribute requirement that could be
encountered. As soon as one of the attributes required to continue is added to the
envelope, cryptlib will delete the required-attribute list and continue, so the attempt to
move the cursor to the next entry in the list will fail and the program will drop out of
the processing loop. For example to try a password against all of the possible
passwords that might decrypt the message that was enveloped above you would use:
int status
/* Get the decryption password from the user */
password = ...;
if( cryptSetAttribute( envelope, CRYPT_ATTRIBUTE_CURRENT_GROUP,
CRYPT_CURSOR_FIRST ) == CRYPT_OK )
do
{
CRYPT_ATTRIBUTE_TYPE requiredAttribute;
/* Get the type of the required attribute at the cursor position
*/
cryptGetAttribute( envelope, CRYPT_ATTRIBUTE_CURRENT,
&requiredAttribute );
/* Make sure we really do require a password resource */
if( requiredAttribute != CRYPT_ENVINFO_PASSWORD )
/* Error */;
/* Try the password. If everything is OK, we'll drop out of the
loop */
status = cryptSetAttributeString( envelope,
CRYPT_ENVINFO_PASSWORD, password, passwordLength );
}
while( status == CRYPT_WRONGKEY && \
cryptSetAttribute( envelope, CRYPT_ATTRIBUTE_CURRENT_GROUP,
CRYPT_CURSOR_NEXT ) == CRYPT_OK );
This steps through each required attribute in turn and tries the supplied password to
see if it matches. As soon as the password matches, the data can be decrypted, and
we drop out of the loop and continue the de-enveloping process.
To extend this a bit further, let’s assume that the data could be enveloped using a
password or a public key (requiring a private decryption key to decrypt it, either one
from a keyset or a crypto device such as a smart card or Fortezza card). The code
inside the loop above then becomes:
CRYPT_ATTRIBUTE_TYPE requiredAttribute;
/* Get the type of the required resource at the cursor position */
cryptGetAttribute( envelope, CRYPT_ATTRIBUTE_CURRENT,
&requiredAttribute );
/* If the decryption is being handled via a crypto device, we don't
need to take any further action, the data has already been
decrypted */
if( requiredAttribute != CRYPT_ATTRIBUTE_NONE )
{
/* Make sure we really do require a password attribute */
if( requiredAttribute != CRYPT_ENVINFO_PASSWORD && \
requiredAttribute != CRYPT_ENVINFO_PRIVATEKEY )
/* Error */;
/* Try the password. If everything is OK, we'll drop out of the
loop */
status = cryptSetAttributeString( envelope, CRYPT_ENVINFO_PASSWORD,
password, passwordLength );
}