📄 devices.c
字号:
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 );
cryptCreateCert( &cryptCert, CRYPT_UNUSED,
CRYPT_CERTTYPE_CERTIFICATE );
status = cryptSetAttribute( cryptCert,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, signContext );
if( cryptStatusOK( status ) && \
!addCertFields( cryptCert, paaCertData ) )
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 );
}
else
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( &cryptSession, CRYPT_UNUSED,
CRYPT_SESSION_CMP_SERVER );
if( cryptStatusError( status ) )
{
printf( "\ncryptCreateSession() failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
status = cryptSetAttribute( cryptSession,
CRYPT_SESSINFO_PRIVATEKEY, cryptPrivateKey );
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptSession,
CRYPT_SESSINFO_KEYSET, cryptCertStore );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptSession, "cryptSetAttribute()",
status, __LINE__ ) );
if( !setConnectInfo( cryptSession, SERVER_MACHINE_ADDRESS,
SERVER_MACHINE_PORT, NET_TIMEOUT ) )
return( FALSE );
puts( " done." );
/* Activate the session */
status = activatePersistentServerSession( cryptSession );
if( cryptStatusError( status ) )
return( extErrorExit( cryptSession, "Attempt to activate CMP "
"server session", status, __LINE__ ) );
/* Clean up */
cryptDestroySession( cryptSession );
if( !caCertTrusted )
cryptSetAttribute( cryptPrivateKey,
CRYPT_CERTINFO_TRUSTED_IMPLICIT, 0 );
return( TRUE );
}
/* Run the PnP PKI client */
static int pnpClient( const CRYPT_DEVICE cryptDevice, const char *userID,
const char *issuePW )
{
CRYPT_SESSION cryptSession;
int status;
/* Create the CMP session and set up the information we need for the
plug-and-play PKI process */
printf( "Creating CMP client session..." );
status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
CRYPT_SESSION_CMP );
if( cryptStatusError( status ) )
{
printf( "\ncryptCreateSession() failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
status = cryptSetAttributeString( cryptSession,
CRYPT_SESSINFO_USERNAME, userID,
paramStrlen( userID ) );
if( cryptStatusOK( status ) )
status = cryptSetAttributeString( cryptSession,
CRYPT_SESSINFO_PASSWORD,
issuePW, paramStrlen( issuePW ) );
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptSession,
CRYPT_SESSINFO_CMP_PRIVKEYSET,
cryptDevice );
if( cryptStatusError( status ) )
{
printf( "\nAddition of session information failed with error code "
"%d, line %d.\n", status, __LINE__ );
return( FALSE );
}
if( !setConnectInfo( cryptSession, SERVER_MACHINE_ADDRESS,
SERVER_MACHINE_PORT, NET_TIMEOUT ) )
return( FALSE );
puts( " done." );
/* Activate the session */
printf( "Obtaining keys and certs..." );
status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
if( cryptStatusError( status ) )
{
printExtError( cryptSession, "\nAttempt to activate plug-a
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -