📄 testscrt.c
字号:
}
}
/* Create the CMP session and revocation request */
cryptSession = createCmpSession( cryptCACert, caInfoPtr->url,
caInfoPtr->user, caInfoPtr->password,
privateKey, TRUE, FALSE, FALSE );
if( privateKey != CRYPT_UNUSED )
cryptDestroyContext( privateKey );
if( cryptSession <= 0 )
return( cryptSession );
cryptCmpRequest = createCmpRevRequest( cryptCert );
if( !cryptCmpRequest )
return( FALSE );
/* Set up the request and activate the session */
status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_REQUEST,
cryptCmpRequest );
cryptDestroyCert( cryptCmpRequest );
if( cryptStatusError( status ) )
{
printf( "cryptSetAttribute() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
if( cryptStatusError( status ) )
{
printExtError( cryptSession, "Attempt to activate CMP client session",
status, __LINE__ );
cryptDestroySession( cryptSession );
if( cryptCert != certToRevoke )
cryptDestroyCert( cryptCert );
if( status == CRYPT_ERROR_OPEN || status == CRYPT_ERROR_READ )
{
/* These servers are constantly appearing and disappearing so if
we get a straight connect error we don't treat it as a serious
failure */
puts( " (Server could be down, faking it and continuing...)\n" );
return( CRYPT_ERROR_FAILED );
}
if( status == CRYPT_ERROR_FAILED )
{
/* A general failed response is more likely to be due to the
server doing something unexpected than a cryptlib problem so
we don't treat it as a fatal error */
puts( " (This is more likely to be an issue with the server than "
"with cryptlib,\n faking it and continuing...)\n" );
return( CRYPT_ERROR_FAILED );
}
return( FALSE );
}
/* Clean up */
if( cryptCert != certToRevoke )
cryptDestroyCert( cryptCert );
cryptDestroySession( cryptSession );
printf( "%s processing succeeded.\n\n", description );
return( TRUE );
}
/* Test the full range of CMP functionality. This performs the following
tests:
RSA sign:
ir + ip + reject (requires cmp.c mod)
ir + ip + certconf + pkiconf
kur + kup + certconf + pkiconf
cr + cp + certconf + pkiconf (not performed since same as kur)
rr + rp (of ir cert)
rr + rp (of kur cert)
RSA encr.:
ir + ip + reject (requires cmp.c mod)
ir + ip + certconf + pkiconf
rr + rp (of ir cert)
DSA:
cr + cp + certconf + pkiconf (success implies that ir/kur/rr
works since they've already been tested for RSA) */
static int connectCMP( const BOOLEAN usePKIBoot )
{
CRYPT_CERTIFICATE cryptCACert = CRYPT_UNUSED, cryptCert;
BYTE readFileName[ BUFFER_SIZE ], writeFileName[ BUFFER_SIZE ];
#if ( CA_NO == 1 ) || ( CA_NO == 10 )
CA_INFO cryptlibCAInfo, *caInfoPtr = &cryptlibCAInfo;
#ifdef TEST_IR
char userID[ 64 ], issuePW[ 64 ];
#endif /* TEST_IR */
#else
const CA_INFO *caInfoPtr = &caInfo[ CA_NO ];
#endif /* cryptlib */
int status;
#if ( CA_NO == 1 ) || ( CA_NO == 10 )
/* Set up the fixed info in the CA info record */
memcpy( &cryptlibCAInfo, &caInfo[ CA_NO ], sizeof( CA_INFO ) );
cryptlibCAInfo.name = "cryptlib";
#ifndef TEST_IR
/* If we're not doing an initialisation request (which fetches user info
for the request), make sure that the required user info is present.
If it isn't, cryptlib's CA auditing will detect a request from a
nonexistant user and refuse to issue a certificate */
status = getPkiUserInfo( NULL, NULL, NULL );
if( cryptStatusError( status ) )
{
puts( "CA certificate store doesn't contain the PKI user "
"information needed to\nauthenticate certificate issue "
"operations, can't perform CMP test." );
return( FALSE );
}
#endif /* TEST_IR */
#endif /* cryptlib CA_NO == 1 or CA_NO == 10 */
/* Get the cert of the CA who will issue the cert unless we're doing a
PKIBoot, in which case the cert is obtained during the PKIBoot
process */
#if ( CA_NO != 1 ) && ( CA_NO != 10 )
printf( "Using the %s CMP server.\n", caInfoPtr->name );
#endif /* !cryptlib */
#if CA_NO != 10
status = importCertFromTemplate( &cryptCACert, CMP_CA_FILE_TEMPLATE,
CA_NO );
if( cryptStatusError( status ) )
{
printf( "Couldn't get CMP CA certificate, status = %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
#endif /* PKIBoot */
/* Test each cert request type: Initialisation, cert request using cert
from initialisation for authentication, key update of cert from
initialisation, revocation of both certs. We insert a 1s delay
between requests to give the server time to recycle */
/* Initialisation request */
#ifdef TEST_IR
#if ( CA_NO == 1 ) || ( CA_NO == 10 )
/* cryptlib implements per-user (rather than shared interop) IDs and
passwords so we need to read the user ID and password information
before we can perform any operations */
status = getPkiUserInfo( userID, issuePW, NULL );
if( cryptStatusError( status ) )
{
#if CA_NO != 10
cryptDestroyCert( cryptCACert );
#endif /* PKIBoot */
return( ( status == CRYPT_ERROR_NOTAVAIL ) ? TRUE : FALSE );
}
/* Set up the variable info in the CA info record */
cryptlibCAInfo.user = userID;
cryptlibCAInfo.password = issuePW;
#endif /* cryptlib CA_NO == 1 or CA_NO == 10 */
/* Initialisation. We define REVOKE_FIRST_CERT to indicate that we can
revoke this one later on */
#define REVOKE_FIRST_CERT
filenameFromTemplate( writeFileName, CMP_PRIVKEY_FILE_TEMPLATE, 1 );
status = requestCert( "RSA signing cert.init.request", caInfoPtr, NULL,
usePKIBoot ? NULL : writeFileName,
#ifdef SERVER_PROVIDES_DN
cmpRsaSignRequestNoDNData,
#else
cmpRsaSignRequestData,
#endif /* SERVER_PROVIDES_DN */
CRYPT_ALGO_RSA, cryptCACert, usePKIBoot,
&cryptCert );
if( status != TRUE )
{
/* If this is the self-test and there's a non-fatal error, make sure
we don't fail with a CRYPT_ERROR_INCOMPLETE when we're finished */
cryptDestroyCert( cryptCACert );
return( status );
}
if( usePKIBoot )
{
/* If we're testing the PKIBoot capability, there's only a single
request to process */
cryptDestroyCert( cryptCACert );
return( TRUE );
}
delayThread( 1 );
#endif /* TEST_IR */
/* Cert request. We have to perform this test before the kur since some
CAs implicitly revoke the cert being replaced, which means we can't
use it to authenticate requests any more once the kur has been
performed */
#ifdef TEST_CR
/* We define REVOKE_SECOND_CERT to indicate that we can revoke this one
later on alongside the ir/kur'd cert, and save a copy to a file for
later use */
#define REVOKE_SECOND_CERT
filenameFromTemplate( readFileName, CMP_PRIVKEY_FILE_TEMPLATE, 1 );
filenameFromTemplate( writeFileName, CMP_PRIVKEY_FILE_TEMPLATE, 2 );
status = requestCert( "RSA signing certificate request", caInfoPtr,
readFileName, writeFileName, cmpRsaSignRequestData,
CRYPT_ALGO_RSA, cryptCACert, FALSE, NULL );
if( status != TRUE )
{
#if defined( TEST_IR )
cryptDestroyCert( cryptCert );
#endif /* TEST_IR || TEST_KUR */
cryptDestroyCert( cryptCACert );
return( status );
}
delayThread( 1 );
#endif /* TEST_CR */
/* Key update request */
#ifdef TEST_KUR
#ifdef TEST_IR
/* We just created the cert, delete it so we can replace it with the
updated form */
cryptDestroyCert( cryptCert );
#endif /* TEST_IR */
/* If it's a CA that implicitly revokes the cert being replaced (in
which case tracking things gets a bit too complicated since we now
need to use the updated rather than original cert to authenticate the
request) we just leave it unrevoked (the first cert is always
revoked) */
#if ( CA_NO == 1 ) || ( CA_NO == 10 )
#undef REVOKE_FIRST_CERT
#endif /* cryptlib */
/* Key update */
filenameFromTemplate( readFileName, CMP_PRIVKEY_FILE_TEMPLATE, 1 );
status = requestCert( "RSA signing certificate update", caInfoPtr,
readFileName, NULL, NULL, CRYPT_UNUSED,
cryptCACert, FALSE, &cryptCert );
if( status != TRUE )
{
cryptDestroyCert( cryptCACert );
return( status );
}
delayThread( 1 );
#endif /* TEST_KUR */
#if 0
/* DSA cert request. We have to get this now because we're about to
revoke the cert we're using to sign the requests */
filenameFromTemplate( readFileName, CMP_PRIVKEY_FILE_TEMPLATE, 1 );
status = requestCert( "DSA certificate", caInfoPtr, readFileName, NULL,
cmpDsaRequestData, CRYPT_ALGO_DSA, cryptCACert,
FALSE, NULL );
if( status != TRUE )
return( status );
delayThread( 1 );
#endif /* 0 */
#if 0
/* Encryption-only cert request. This test requires a change in
certsign.c because when creating a cert request cryptlib always
allows signing for the request even if it's an encryption-only key
(this is required for PKCS #10, see the comment in the kernel code).
Because of this a request will always appear to be associated with a
signature-enabled key so it's necessary to make a code change to
disallow this. Disallowing sigs for encryption-only keys would break
PKCS #10 since it's then no longer possible to create the self-signed
request, this is a much bigger concern than CMP. Note that this
functionality is tested by the PnP PKI test, which creates the
necessary encryption-only requests internally and can do things that
we can't do from the outside */
status = requestCert( "RSA encryption certificate", caInfoPtr,
readFileName, writeFileName, cmpRsaEncryptRequestData,
CRYPT_ALGO_RSA, cryptCACert, FALSE, NULL );
if( status != TRUE )
return( status );
delayThread( 1 );
#endif /* 0 */
/* Revocation request */
#ifdef TEST_RR
filenameFromTemplate( readFileName, CMP_PRIVKEY_FILE_TEMPLATE, 1 );
#ifdef REVOKE_FIRST_CERT
#if CA_NO == 2
status = revokeCert( "RSA initial/updated certificate", caInfoPtr,
readFileName, cryptCert, cryptCACert, TRUE );
#else
status = revokeCert( "RSA initial/updated certificate", caInfoPtr,
readFileName, cryptCert, cryptCACert, FALSE );
#endif /* Certicom requires signed request */
cryptDestroyCert( cryptCert );
delayThread( 1 );
#elif !defined( TEST_KUR ) || ( ( CA_NO != 1 ) && ( CA_NO != 10 ) )
/* We didn't issue the first cert in this run, try revoking it from
the cert stored in the key file unless we're talking to a CA that
implicitly revokes the cert being replaced during a kur */
status = revokeCert( "RSA initial/updated certificate", caInfoPtr,
readFileName, CRYPT_UNUSED, cryptCACert, TRUE );
#else
/* This is a kur'd cert for which the original has been implicitly
revoked, we can't do much else with it */
cryptDestroyCert( cryptCert );
#endif /* REVOKE_FIRST_CERT */
if( status != TRUE )
{
cryptDestroyCert( cryptCACert );
return( status );
}
#ifdef REVOKE_SECOND_CERT
/* We requested a second cert, revoke that too. Note that we have to
sign this with the second cert since the first one may have just been
revoked */
filenameFromTemplate( readFileName, CMP_PRIVKEY_FILE_TEMPLATE, 2 );
status = revokeCert( "RSA signing certificate", caInfoPtr, readFileName,
CRYPT_UNUSED, cryptCACert, TRUE );
if( status != TRUE )
{
cryptDestroyCert( cryptCACert );
return( status );
}
#endif /* REVOKE_SECOND_CERT */
#endif /* TEST_RR */
/* Clean up */
cryptDestroyCert( cryptCACert );
return( TRUE );
}
int testSessionCMP( void )
{
return( connectCMP( FALSE ) );
}
/* Test the plug-and-play PKI functionality */
static int connectPNPPKI( void )
{
CRYPT_SESSION cryptSession;
CRYPT_KEYSET cryptKeyset;
char userID[ 64 ], issuePW[ 64 ];
int status;
/* Create the CMP session */
status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
CRYPT_SESSION_CMP );
if( status == CRYPT_ERROR_PARAM3 ) /* CMP session access not available */
return( CRYPT_ERROR_NOTAVAIL );
if( cryptStatusError( status ) )
{
printf( "cryptCreateSession() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Create the keyset to contain the keys */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
CRYPT_KEYSET_FILE, PNP_PRIVKEY_FILE,
CRYPT_KEYOPT_CREATE );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Get information needed for enrolment */
status = getPkiUserInfo( userID, issuePW, NULL );
if( cryptStatusError( status ) )
return( ( status == CRYPT_ERROR_NOTAVAIL ) ? TRUE : FALSE );
/* Set up the information we need for the plug-and-play PKI process */
status = cryptSetAttributeString( cryptSession,
CRYPT_SESSINFO_USERNAME, userID,
strlen( userID ) );
if( cryptStatusOK( status ) )
status = cryptSetAttributeString( cryptSession,
CRYPT_SESSINFO_PASSWORD,
issuePW, strlen( issuePW ) );
if( cryptStatusOK( status ) )
status = cryptSetAttributeString( cryptSession,
CRYPT_SESSINFO_SERVER_NAME,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -