📄 devices.c
字号:
printf( "Device label is '%s'.\n", tokenLabel );
}
/* See if we need to authenticate ourselves */
status = cryptGetAttribute( cryptDevice, CRYPT_DEVINFO_LOGGEDIN,
&loggedOn );
if( cryptStatusError( status ) )
{
puts( "Couldn't obtain device login status." );
return( FALSE );
}
if( loggedOn )
{
/* Device may not require a login, or has already been logged in
via a keypad or similar mechanism */
puts( "Device is already logged in, skipping login." );
return( TRUE );
}
/* Try and log in */
printf( "Logging on to the device..." );
status = cryptSetAttributeString( cryptDevice,
CRYPT_DEVINFO_AUTHENT_USER, userPIN,
strlen( userPIN ) );
if( status == CRYPT_ERROR_INITED )
{
/* Some devices may not require any login, in which case we're
done */
puts( " device is already logged in." );
return( TRUE );
}
if( status == CRYPT_ERROR_NOTINITED )
{
/* It's an uninitialised device, tell the user and exit */
puts( " device needs to be initialised." );
return( FALSE );
}
if( cryptStatusError( status ) )
{
printf( "\nDevice login failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( " done." );
return( TRUE );
}
/* Initialise a device */
static int initDevice( const CRYPT_DEVICE cryptDevice,
const char *defaultSSOPIN, const char *ssoPIN,
const char *userPIN )
{
int status;
/* PKCS #11 doesn't distinguish between zeroisation and initialisation,
so we need to zeroise the device if it's a Fortezza card */
if( CLIENT_DEVICE_TYPE == CRYPT_DEVICE_FORTEZZA )
{
printf( "Zeroising device..." );
status = cryptSetAttributeString( cryptDevice,
CRYPT_DEVINFO_ZEROISE, FORTEZZA_ZEROISE_PIN,
strlen( FORTEZZA_ZEROISE_PIN ) );
if( cryptStatusError( status ) )
{
printf( "\nCouldn't zeroise device, status = %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( " done." );
}
/* Initialise the device and set the SO PIN */
printf( "Initialising device with default SO PIN '%s'...",
defaultSSOPIN );
status = cryptSetAttributeString( cryptDevice, CRYPT_DEVINFO_INITIALISE,
defaultSSOPIN, strlen( defaultSSOPIN ) );
if( cryptStatusError( status ) )
{
printf( "\nCouldn't initialise device, status = %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( " done." );
printf( "Setting SO PIN to '%s'...", ssoPIN );
status = cryptSetAttributeString( cryptDevice,
CRYPT_DEVINFO_SET_AUTHENT_SUPERVISOR,
ssoPIN, strlen( ssoPIN ) );
if( cryptStatusError( status ) )
{
printf( "\nCouldn't set SO PIN, status = %d, line %d.\n", status,
__LINE__ );
return( FALSE );
}
puts( " done." );
/* If it's a Fortezza card, create a dummy PAA key and install its cert.
We have to do it at this point because the operation is only allowed
in the SSO initialised state. In addition we can't use the card for
this operation because cert slot 0 is a data-only slot (that is, it
can't correspond to a key held on the card), so we create a dummy
external cert and use that */
if( CLIENT_DEVICE_TYPE == CRYPT_DEVICE_FORTEZZA )
{
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT signContext;
printf( "Loading PAA certificate..." );
if( !loadDSAContexts( CRYPT_UNUSED, &signContext, NULL ) )
return( FALSE );
status = cryptCreateCert( &cryptCert, CRYPT_UNUSED,
CRYPT_CERTTYPE_CERTIFICATE );
if( cryptStatusError( status ) )
return( FALSE );
status = cryptSetAttribute( cryptCert,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, signContext );
if( cryptStatusOK( status ) && \
!addCertFields( cryptCert, paaCertData, __LINE__ ) )
return( FALSE );
if( cryptStatusOK( status ) )
status = cryptSignCert( cryptCert, signContext );
cryptDestroyContext( signContext );
if( cryptStatusError( status ) )
{
cryptDestroyCert( cryptCert );
printf( "\nCreation of certificate failed with error code %d, "
"line %d.\n", status, __LINE__ );
return( FALSE );
}
status = cryptAddPublicKey( cryptDevice, cryptCert );
cryptDestroyCert( cryptCert );
if( cryptStatusError( status ) )
{
printf( "\ncryptAddPublicKey() failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
puts( " done." );
}
/* Set the user PIN and log on as the user. Some devices automatically
log the user in when they set the user password, however, for some
devices this is a pseudo-login for which any subsequent operations
fail with a not-logged-in error or something similar, so rather than
relying on the existing login we always (re-)log in, which performs
an explicit logoff if we're already logged in at the time */
printf( "Setting user PIN to '%s'...", userPIN );
status = cryptSetAttributeString( cryptDevice,
CRYPT_DEVINFO_SET_AUTHENT_USER,
userPIN, strlen( userPIN ) );
if( cryptStatusOK( status ) )
status = cryptSetAttributeString( cryptDevice,
CRYPT_DEVINFO_AUTHENT_USER,
userPIN, strlen( userPIN ) );
if( cryptStatusError( status ) )
{
printf( "\nCouldn't set user PIN/log on as user, status = %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
puts( " done." );
return( TRUE );
}
/* Open a cert store */
static int openCertStore( CRYPT_KEYSET *cryptCertStore )
{
int status;
/* Clear return value */
*cryptCertStore = -1;
/* Open the cert store */
printf( "Opening CA certificate store..." );
status = cryptKeysetOpen( cryptCertStore, CRYPT_UNUSED,
CRYPT_KEYSET_ODBC_STORE, "testcertstore",
CRYPT_KEYOPT_CREATE );
if( status == CRYPT_ERROR_DUPLICATE )
status = cryptKeysetOpen( cryptCertStore, CRYPT_UNUSED,
CRYPT_KEYSET_ODBC_STORE, "testcertstore",
CRYPT_KEYOPT_NONE );
if( cryptStatusError( status ) )
{
printf( "\ncryptKeysetOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( " done." );
return( TRUE );
}
/* Add a PKI user to a cert store */
static int initUserInfo( const CRYPT_KEYSET cryptCertStore,
const char *userName )
{
CRYPT_CERTIFICATE cryptPKIUser;
int length, status;
/* Create the PKI user object and add the user's identification
information */
printf( "Creating PKI user..." );
status = cryptCreateCert( &cryptPKIUser, CRYPT_UNUSED,
CRYPT_CERTTYPE_PKIUSER );
if( cryptStatusError( status ) )
{
printf( "\ncryptCreateCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptSetAttributeString( cryptPKIUser,
CRYPT_CERTINFO_COMMONNAME, userName,
strlen( userName ) );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptPKIUser, "cryptSetAttributeString()",
status, __LINE__ ) );
puts( " done." );
/* Add the user info to the cert store */
printf( "Adding PKI user to CA certificate store..." );
status = cryptCAAddItem( cryptCertStore, cryptPKIUser );
if( status == CRYPT_ERROR_DUPLICATE )
{
char userCN[ CRYPT_MAX_TEXTSIZE + 1 ];
/* The PKI user info is already present from a previous run, get the
existing info */
printf( "\nPKI user information is already present from a previous "
"run, re-using existing\n PKI user data..." );
status = cryptGetAttributeString( cryptPKIUser,
CRYPT_CERTINFO_COMMONNAME,
userCN, &length );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptPKIUser, "cryptGetAttribute()",
status, __LINE__ ) );
userCN[ length ] = '\0';
cryptDestroyCert( cryptPKIUser );
status = cryptCAGetItem( cryptCertStore, &cryptPKIUser,
CRYPT_CERTTYPE_PKIUSER, CRYPT_KEYID_NAME,
userCN );
}
if( cryptStatusError( status ) )
return( extErrorExit( cryptCertStore, "cryptCAAddItem()", status,
__LINE__ ) );
puts( " done." );
/* Display the information for the user */
if( !printCertInfo( cryptPKIUser ) )
return( FALSE );
/* Clean up */
cryptDestroyCert( cryptPKIUser );
return( TRUE );
}
/* Get details for a PKI user */
static int getUserInfo( char *userID, char *issuePW )
{
#ifndef CLIENT_ID
CRYPT_KEYSET cryptCertStore;
CRYPT_CERTIFICATE cryptPKIUser;
int length, status;
/* Get the PKIUser object from the cert store */
status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED,
CRYPT_KEYSET_ODBC_STORE, "testcertstore",
CRYPT_KEYOPT_NONE );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptCAGetItem( cryptCertStore, &cryptPKIUser,
CRYPT_CERTTYPE_PKIUSER, CRYPT_KEYID_NAME,
"Test PKI user" );
cryptKeysetClose( cryptCertStore );
if( cryptStatusError( status ) )
return( extErrorExit( cryptCertStore, "cryptCAGetItem()", status,
__LINE__ ) );
/* Extract the information from the PKIUser object */
status = cryptGetAttributeString( cryptPKIUser,
CRYPT_CERTINFO_PKIUSER_ID,
userID, &length );
if( cryptStatusOK( status ) )
{
userID[ length ] = '\0';
status = cryptGetAttributeString( cryptPKIUser,
CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD,
issuePW, &length );
}
if( cryptStatusOK( status ) )
issuePW[ length ] = '\0';
cryptDestroyCert( cryptPKIUser );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptPKIUser, "cryptGetAttribute()", status,
__LINE__ ) );
#else
strcpy( userID, CLIENT_ID );
strcpy( issuePW, CLIENT_AUTHENTICATOR );
#endif /* CLIENT_ID */
/* We've got what we need, tell the user what we're doing */
printf( "Using user name %s, password %s.\n", userID, issuePW );
return( TRUE );
}
/* Run the PnP PKI server */
static int pnpServer( const CRYPT_DEVICE cryptDevice,
const CRYPT_KEYSET cryptCertStore )
{
CRYPT_SESSION cryptSession;
CRYPT_CONTEXT cryptPrivateKey;
int caCertTrusted, status;
/* Perform a cleanup action to remove any leftover requests from
previous runs */
cryptCACertManagement( NULL, CRYPT_CERTACTION_CLEANUP, cryptCertStore,
CRYPT_UNUSED, CRYPT_UNUSED );
/* Get the CA's key from the device and make it trusted for PKIBoot
functionality. If we're running the test in loopback mode with the
Fortezza interface we can't have both the client and server using
Fortezza cards due to Spyrus driver bugs, and also can't have the
client and server as PKCS #11 and Fortezza due to other driver bugs,
so we have to fake the CA key using a software-only implementation */
printf( "Making CA cert trusted for PKIBoot..." );
#ifndef CLIENT_ID
if( CLIENT_DEVICE_TYPE == CRYPT_DEVICE_FORTEZZA )
status = getPrivateKey( &cryptPrivateKey, CA_PRIVKEY_FILE,
CA_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
else
#endif /* CLIENT_ID */
status = cryptGetPrivateKey( cryptDevice, &cryptPrivateKey,
CRYPT_KEYID_NAME, "CA key", NULL );
if( cryptStatusError( status ) )
{
printf( "\nCA private key read failed with error code %d, "
"line %d.\n", status, __LINE__ );
return( FALSE );
}
cryptGetAttribute( cryptPrivateKey, CRYPT_CERTINFO_TRUSTED_IMPLICIT,
&caCertTrusted );
cryptSetAttribute( cryptPrivateKey, CRYPT_CERTINFO_TRUSTED_IMPLICIT, 1 );
puts( " done." );
/* Create the CMP session and add the CA key and cert store */
printf( "Creating CMP server session..." );
status = cryptCreateSession( &cr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -