1 /****************************************************************************
2 * *
3 * cryptlib Test Code *
4 * Copyright Peter Gutmann 1995-2011 *
5 * *
6 ****************************************************************************/
7
8 #include "cryptlib.h"
9 #include "test/test.h"
10
11 #if defined( __MVS__ ) || defined( __VMCMS__ )
12 /* Suspend conversion of literals to ASCII. */
13 #pragma convlit( suspend )
14 #endif /* IBM big iron */
15 #if defined( __ILEC400__ )
16 #pragma convert( 0 )
17 #endif /* IBM medium iron */
18
19 /****************************************************************************
20 * *
21 * Utility Routines *
22 * *
23 ****************************************************************************/
24
25 /* The tests that use databases and certificate stores require that the user
26 set up a suitable ODBC data source (at least when running under Windows),
27 to automate this process we try and create the data source if it isn't
28 present.
29
30 This is complicated by the fact that the universal default MSJET database
31 driver doesn't have a 64-bit version so it's not possible to use it under
32 Vista/Windows 7 x64. To work around this we fall back to the SQL Server
33 driver, which replaces MSJET on x64 systems */
34
35 #if defined( _MSC_VER ) && defined( _WIN32 ) && !defined( _WIN32_WCE )
36
37 #define DATABASE_AUTOCONFIG
38
39 #include <odbcinst.h>
40
41 #define DRIVER_NAME TEXT( "Microsoft Access Driver (*.MDB)" )
42 #define DATABASE_ATTR_NAME "DSN=" DATABASE_KEYSET_NAME_ASCII "#" \
43 "DESCRIPTION=cryptlib test key database#" \
44 "DBQ="
45 #define DATABASE_ATTR_CREATE "DSN=" DATABASE_KEYSET_NAME_ASCII "#" \
46 "DESCRIPTION=cryptlib test key database#" \
47 "CREATE_DB="
48 #define DATABASE_ATTR_TAIL DATABASE_KEYSET_NAME_ASCII ".mdb#"
49 #define CERTSTORE_ATTR_NAME "DSN=" CERTSTORE_KEYSET_NAME_ASCII "#" \
50 "DESCRIPTION=cryptlib test key database#" \
51 "DBQ="
52 #define CERTSTORE_ATTR_CREATE "DSN=" CERTSTORE_KEYSET_NAME_ASCII "#" \
53 "DESCRIPTION=cryptlib test key database#" \
54 "CREATE_DB="
55 #define CERTSTORE_ATTR_TAIL CERTSTORE_KEYSET_NAME_ASCII ".mdb#"
56
57 #define DRIVER_NAME_ALT TEXT( "SQL Server" )
58 #define DATABASE_ATTR_NAME_ALT "DSN=" DATABASE_KEYSET_NAME_ASCII "#" \
59 "DESCRIPTION=cryptlib test key database#" \
60 "Server=localhost#" \
61 "Database="
62 #define DATABASE_ATTR_CREATE_ALT ""
63 #define DATABASE_ATTR_TAIL_ALT DATABASE_KEYSET_NAME_ASCII "#"
64 #define CERTSTORE_ATTR_NAME_ALT "DSN=" CERTSTORE_KEYSET_NAME_ASCII "#" \
65 "DESCRIPTION=cryptlib test key database#" \
66 "Server=localhost#" \
67 "Database="
68 #define CERTSTORE_ATTR_CREATE_ALT ""
69 #define CERTSTORE_ATTR_TAIL_ALT CERTSTORE_KEYSET_NAME_ASCII "#"
70
buildDBString(char * buffer,const char * attrName,const char * attrTail,const char * path)71 static void buildDBString( char *buffer, const char *attrName,
72 const char *attrTail, const char *path )
73 {
74 const int attrNameSize = strlen( attrName );
75 const int attrTailSize = strlen( attrTail ) + 1;
76 const int pathSize = strlen( path );
77 int dbStringLen, i;
78
79 /* Build up the data-source control string */
80 memcpy( buffer, attrName, attrNameSize + 1 );
81 memcpy( buffer + attrNameSize, path, pathSize );
82 if( attrTailSize > 0 )
83 {
84 memcpy( buffer + attrNameSize + pathSize, attrTail,
85 attrTailSize );
86 }
87 buffer[ attrNameSize + pathSize + attrTailSize ] = '\0';
88
89 /* Finally, convert the strings to the weird embedded-null strings
90 required by SQLConfigDataSource() */
91 dbStringLen = strlen( buffer );
92 for( i = 0; i < dbStringLen; i++ )
93 {
94 if( buffer[ i ] == '#' )
95 buffer[ i ] = '\0';
96 }
97 }
98
reportSqlError(const BOOLEAN isSqlServer)99 static void reportSqlError( const BOOLEAN isSqlServer )
100 {
101 DWORD dwErrorCode;
102 WORD errorMessageLen;
103 char errorMessage[ 256 ];
104
105 if( SQLInstallerError( 1, &dwErrorCode, errorMessage, 256,
106 &errorMessageLen ) != SQL_NO_DATA )
107 {
108 printf( "SQLConfigDataSource() returned error code %d,\n "
109 "message '%s'.\n", dwErrorCode, errorMessage );
110 #if defined( _M_X64 )
111 if( !isSqlServer )
112 {
113 puts( " (This is probably because there's no appropriate "
114 "64-bit driver present,\n retrying the create with "
115 "an alternative driver...)." );
116 }
117 #endif /* _M_X64 */
118 }
119 else
120 {
121 puts( "SQLConfigDataSource() failed, no additional information "
122 "available" );
123 }
124 }
125
createDatabase(const char * driverName,const char * keysetName,const char * nameString,const char * createString,const char * trailerString,const BOOLEAN isSqlServer)126 static BOOLEAN createDatabase( const char *driverName,
127 const char *keysetName,
128 const char *nameString,
129 const char *createString,
130 const char *trailerString,
131 const BOOLEAN isSqlServer )
132 {
133 char tempPathBuffer[ 512 ];
134 char attrBuffer[ 1024 ];
135 #ifdef UNICODE_STRINGS
136 wchar_t wcAttrBuffer[ 1024 ];
137 #endif /* UNICODE_STRINGS */
138 int status;
139
140 if( !GetTempPath( 512, tempPathBuffer ) )
141 strcpy( tempPathBuffer, "C:\\Temp\\" );
142
143 /* Try and create the DSN. For the default Access driver his is a two-
144 step process, first we create the DSN and then the underlying file
145 that contains the database. For SQL Server it's simpler, the database
146 server already exists so all we have to do is create the database */
147 if( isSqlServer )
148 {
149 printf( "Attempting to create keyset '%s' using alternative\n "
150 "data source (ODBC - SQL Server)...\n", keysetName );
151 puts( " (Autoconfiguration of SQL Server data sources rather than "
152 "having them\n configured manually by an administrator can "
153 "be erratic, if cryptlib\n hangs while trying to access the "
154 "certificate database then you need to\n configure the SQL "
155 "Server data source manually)." );
156 }
157 else
158 {
159 printf( "Database keyset '%s' not found, attempting to create\n "
160 "data source (ODBC - MS Access)...\n", keysetName );
161 }
162 buildDBString( attrBuffer, nameString, trailerString, tempPathBuffer );
163 #ifdef UNICODE_STRINGS
164 mbstowcs( wcAttrBuffer, attrBuffer, strlen( attrBuffer ) + 1 );
165 status = SQLConfigDataSource( NULL, ODBC_ADD_DSN, driverName,
166 wcAttrBuffer );
167 #else
168 status = SQLConfigDataSource( NULL, ODBC_ADD_DSN, driverName,
169 attrBuffer );
170 #endif /* UNICODE_STRINGS */
171 if( status != 1 )
172 {
173 reportSqlError( isSqlServer );
174 return( FALSE );
175 }
176 if( isSqlServer )
177 {
178 /* The server already exists and we're done */
179 return( TRUE );
180 }
181 buildDBString( attrBuffer, createString, trailerString, tempPathBuffer );
182 #ifdef UNICODE_STRINGS
183 mbstowcs( wcAttrBuffer, attrBuffer, strlen( attrBuffer ) + 1 );
184 status = SQLConfigDataSource( NULL, ODBC_ADD_DSN, driverName,
185 wcAttrBuffer );
186 #else
187 status = SQLConfigDataSource( NULL, ODBC_ADD_DSN, driverName,
188 attrBuffer );
189 #endif /* UNICODE_STRINGS */
190 if( status != 1 )
191 {
192 reportSqlError( isSqlServer );
193 return( FALSE );
194 }
195
196 return( TRUE );
197 }
198
checkCreateDatabaseKeyset(void)199 static void checkCreateDatabaseKeyset( void )
200 {
201 CRYPT_KEYSET cryptKeyset;
202 int status;
203
204 /* Check whether the test certificate database can be opened. This can
205 return a CRYPT_ARGERROR_PARAM3 as a normal condition since a freshly-
206 created database is empty and therefore can't be identified as a
207 certificate database until data is written to it */
208 status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
209 CRYPT_KEYSET_ODBC, DATABASE_KEYSET_NAME,
210 CRYPT_KEYOPT_READONLY );
211 if( cryptStatusOK( status ) )
212 {
213 cryptKeysetClose( cryptKeyset );
214 return;
215 }
216 if( status != CRYPT_ERROR_OPEN )
217 return;
218
219 /* Create the database keyset */
220 status = createDatabase( DRIVER_NAME, DATABASE_KEYSET_NAME_ASCII,
221 DATABASE_ATTR_NAME, DATABASE_ATTR_CREATE,
222 DATABASE_ATTR_TAIL, FALSE );
223 if( status == FALSE )
224 {
225 /* The create with the default (MS Access) driver failed, fall back
226 to the SQL server alternative */
227 status = createDatabase( DRIVER_NAME_ALT, DATABASE_KEYSET_NAME_ASCII,
228 DATABASE_ATTR_NAME_ALT,
229 DATABASE_ATTR_CREATE_ALT,
230 DATABASE_ATTR_TAIL_ALT, TRUE );
231 }
232 puts( ( status == TRUE ) ? "Data source creation succeeded." : \
233 "Data source creation failed.\n\nYou need to create the "
234 "keyset data source as described in the cryptlib manual\n"
235 "for the database keyset tests to run." );
236 }
237
checkCreateDatabaseCertstore(void)238 static void checkCreateDatabaseCertstore( void )
239 {
240 CRYPT_KEYSET cryptKeyset;
241 int status;
242
243 /* Check whether the test certificate store database can be opened.
244 This can return a CRYPT_ARGERROR_PARAM3 as a normal condition since a
245 freshly-created database is empty and therefore can't be identified
246 as a certificate store until data is written to it */
247 status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
248 CRYPT_KEYSET_ODBC_STORE, CERTSTORE_KEYSET_NAME,
249 CRYPT_KEYOPT_READONLY );
250 if( cryptStatusOK( status ) )
251 {
252 cryptKeysetClose( cryptKeyset );
253 return;
254 }
255 if( status != CRYPT_ERROR_OPEN )
256 return;
257
258 /* Create the database keyset */
259 status = createDatabase( DRIVER_NAME, CERTSTORE_KEYSET_NAME_ASCII,
260 CERTSTORE_ATTR_NAME, CERTSTORE_ATTR_CREATE,
261 CERTSTORE_ATTR_TAIL, FALSE );
262 if( status == FALSE )
263 {
264 /* The create with the default (MS Access) driver failed, fall back
265 to the SQL server alternative */
266 status = createDatabase( DRIVER_NAME_ALT, CERTSTORE_KEYSET_NAME_ASCII,
267 CERTSTORE_ATTR_NAME_ALT,
268 CERTSTORE_ATTR_CREATE_ALT,
269 CERTSTORE_ATTR_TAIL_ALT, TRUE );
270 }
271 puts( ( status == TRUE ) ? "Data source creation succeeded.\n" : \
272 "Data source creation failed.\n\nYou need to create the "
273 "certificate store data source as described in the\n"
274 "cryptlib manual for the certificate management tests to "
275 "run.\n" );
276 }
277
checkCreateDatabaseKeysets(void)278 static void checkCreateDatabaseKeysets( void )
279 {
280 CRYPT_KEYSET cryptKeyset;
281 int status;
282
283 /* Create the databases */
284 checkCreateDatabaseKeyset();
285 checkCreateDatabaseCertstore();
286
287 /* Create the keysets within the database */
288 status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
289 DATABASE_KEYSET_TYPE, DATABASE_KEYSET_NAME,
290 CRYPT_KEYOPT_CREATE );
291 if( cryptStatusOK( status ) )
292 {
293 printf( "Database keyset created within database '%s'.\n",
294 DATABASE_KEYSET_NAME );
295 cryptKeysetClose( cryptKeyset );
296 }
297 else
298 {
299 if( status != CRYPT_ERROR_DUPLICATE )
300 {
301 printf( "Error %d creating keyset within '%s' database.\n", status,
302 DATABASE_KEYSET_NAME );
303 }
304 }
305 status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
306 CERTSTORE_KEYSET_TYPE, CERTSTORE_KEYSET_NAME,
307 CRYPT_KEYOPT_CREATE );
308 if( cryptStatusOK( status ) )
309 {
310 printf( "Certificate store keyset created within database '%s'.\n",
311 CERTSTORE_KEYSET_NAME );
312 cryptKeysetClose( cryptKeyset );
313 }
314 else
315 {
316 if( status != CRYPT_ERROR_DUPLICATE )
317 {
318 printf( "Error %d creating keyset within '%s' database.\n", status,
319 CERTSTORE_KEYSET_NAME );
320 }
321 }
322 putchar( '\n' );
323 }
324
325 /* External-access function for situations where a database keyset is
326 needed, for example the PKI session tests */
327
initDatabaseKeysets(void)328 void initDatabaseKeysets( void )
329 {
330 /* Create the certificate store database if required */
331 checkCreateDatabaseCertstore();
332 }
333 #endif /* Win32 with VC++ */
334
335 /****************************************************************************
336 * *
337 * Test Low-level Functions *
338 * *
339 ****************************************************************************/
340
341 #ifdef TEST_SELFTEST
342
343 /* Test the cryptlib self-test routines */
344
testSelfTest(void)345 BOOLEAN testSelfTest( void )
346 {
347 int value, status;
348
349 /* Perform the self-test. First we write the value to true to force a
350 self-test, then we read it back to see whether it succeeded */
351 status = cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_SELFTESTOK,
352 TRUE );
353 if( cryptStatusError( status ) )
354 {
355 fprintf( outputStream, "Attempt to perform cryptlib algorithm "
356 "self-test failed with error code %d, line %d.\n", status,
357 __LINE__ );
358 return( FALSE );
359 }
360 status = cryptGetAttribute( CRYPT_UNUSED, CRYPT_OPTION_SELFTESTOK,
361 &value );
362 if( cryptStatusError( status ) || value != TRUE )
363 {
364 /* Unfortunately all that we can report at this point is that the
365 self-test failed, we can't try each algorithm individually
366 because the self-test has disabled the failed one(s) */
367 fprintf( outputStream, "cryptlib algorithm self-test failed, line "
368 "%d.\n", __LINE__ );
369 return( FALSE );
370 }
371 fputs( "cryptlib algorithm self-test succeeded.\n\n", outputStream );
372
373 return( TRUE );
374 }
375 #else
376
testSelfTest(void)377 BOOLEAN testSelfTest( void )
378 {
379 puts( "Skipping test of self-test routines...\n" );
380 return( TRUE );
381 }
382 #endif /* TEST_SELFTEST */
383
384 #ifdef TEST_LOWLEVEL
385
386 /* Test the low-level encryption routines */
387
testLowLevel(void)388 BOOLEAN testLowLevel( void )
389 {
390 CRYPT_ALGO_TYPE cryptAlgo;
391 BOOLEAN algosEnabled;
392
393 /* Test the conventional encryption routines */
394 algosEnabled = FALSE;
395 for( cryptAlgo = CRYPT_ALGO_FIRST_CONVENTIONAL;
396 cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL; cryptAlgo++ )
397 {
398 if( cryptStatusOK( cryptQueryCapability( cryptAlgo, NULL ) ) )
399 {
400 if( !testLowlevel( CRYPT_UNUSED, cryptAlgo, FALSE ) )
401 return( FALSE );
402 algosEnabled = TRUE;
403 }
404 }
405 if( !algosEnabled )
406 puts( "(No conventional-encryption algorithms enabled)." );
407
408 /* Test the public-key encryption routines */
409 algosEnabled = FALSE;
410 for( cryptAlgo = CRYPT_ALGO_FIRST_PKC;
411 cryptAlgo <= CRYPT_ALGO_LAST_PKC; cryptAlgo++ )
412 {
413 if( cryptStatusOK( cryptQueryCapability( cryptAlgo, NULL ) ) )
414 {
415 if( !testLowlevel( CRYPT_UNUSED, cryptAlgo, FALSE ) )
416 return( FALSE );
417 algosEnabled = TRUE;
418 }
419 }
420 if( cryptStatusOK( cryptQueryCapability( CRYPT_ALGO_RSA, NULL ) ) && \
421 !testRSAMinimalKey() )
422 return( FALSE );
423 if( !algosEnabled )
424 puts( "(No public-key algorithms enabled)." );
425
426 /* Test the hash routines */
427 algosEnabled = FALSE;
428 for( cryptAlgo = CRYPT_ALGO_FIRST_HASH;
429 cryptAlgo <= CRYPT_ALGO_LAST_HASH; cryptAlgo++ )
430 {
431 if( cryptStatusOK( cryptQueryCapability( cryptAlgo, NULL ) ) )
432 {
433 if( !testLowlevel( CRYPT_UNUSED, cryptAlgo, FALSE ) )
434 return( FALSE );
435 algosEnabled = TRUE;
436 }
437 }
438 if( !algosEnabled )
439 puts( "(No hash algorithms enabled)." );
440
441 /* Test the MAC routines */
442 algosEnabled = FALSE;
443 for( cryptAlgo = CRYPT_ALGO_FIRST_MAC;
444 cryptAlgo <= CRYPT_ALGO_LAST_MAC; cryptAlgo++ )
445 {
446 if( cryptStatusOK( cryptQueryCapability( cryptAlgo, NULL ) ) )
447 {
448 if( !testLowlevel( CRYPT_UNUSED, cryptAlgo, FALSE ) )
449 return( FALSE );
450 algosEnabled = TRUE;
451 }
452 }
453 if( !algosEnabled )
454 puts( "(No MAC algorithms enabled)." );
455 printf( "\n" );
456
457 return( TRUE );
458 }
459 #else
460
testLowLevel(void)461 BOOLEAN testLowLevel( void )
462 {
463 puts( "Skipping test of low-level encryption routines...\n" );
464 return( TRUE );
465 }
466 #endif /* TEST_LOWLEVEL */
467
468 /****************************************************************************
469 * *
470 * Test Randomness, Config, and Device Functions *
471 * *
472 ****************************************************************************/
473
474 #ifdef TEST_RANDOM
475
476 /* Test the randomness-gathering routines */
477
testRandom(void)478 BOOLEAN testRandom( void )
479 {
480 if( !testRandomRoutines() )
481 {
482 fputs( "The self-test will proceed without using a strong random "
483 "number source.\n\n", outputStream );
484
485 /* Kludge the randomness routines so we can continue the self-tests */
486 cryptAddRandom( "xyzzy", 5 );
487 }
488
489 return( TRUE );
490 }
491 #else
492
testRandom(void)493 BOOLEAN testRandom( void )
494 {
495 puts( "Skipping test of randomness routines...\n" );
496 return( TRUE );
497 }
498 #endif /* TEST_RANDOM */
499
500 #ifdef TEST_CONFIG
501
502 /* The names of the configuration options we check for */
503
504 static struct {
505 const CRYPT_ATTRIBUTE_TYPE option; /* Option */
506 const char FAR_BSS *name; /* Option name */
507 const BOOLEAN isNumeric; /* Whether it's a numeric option */
508 } FAR_BSS configOption[] = {
509 { CRYPT_OPTION_INFO_DESCRIPTION, "CRYPT_OPTION_INFO_DESCRIPTION", FALSE },
510 { CRYPT_OPTION_INFO_COPYRIGHT, "CRYPT_OPTION_INFO_COPYRIGHT", FALSE },
511 { CRYPT_OPTION_INFO_MAJORVERSION, "CRYPT_OPTION_INFO_MAJORVERSION", TRUE },
512 { CRYPT_OPTION_INFO_MINORVERSION, "CRYPT_OPTION_INFO_MINORVERSION", TRUE },
513 { CRYPT_OPTION_INFO_STEPPING, "CRYPT_OPTION_INFO_STEPPING", TRUE },
514
515 { CRYPT_OPTION_ENCR_ALGO, "CRYPT_OPTION_ENCR_ALGO", TRUE },
516 { CRYPT_OPTION_ENCR_HASH, "CRYPT_OPTION_ENCR_HASH", TRUE },
517 { CRYPT_OPTION_ENCR_MAC, "CRYPT_OPTION_ENCR_MAC", TRUE },
518
519 { CRYPT_OPTION_PKC_ALGO, "CRYPT_OPTION_PKC_ALGO", TRUE },
520 { CRYPT_OPTION_PKC_KEYSIZE, "CRYPT_OPTION_PKC_KEYSIZE", TRUE },
521
522 { CRYPT_OPTION_SIG_ALGO, "CRYPT_OPTION_SIG_ALGO", TRUE },
523 { CRYPT_OPTION_SIG_KEYSIZE, "CRYPT_OPTION_SIG_KEYSIZE", TRUE },
524
525 { CRYPT_OPTION_KEYING_ALGO, "CRYPT_OPTION_KEYING_ALGO", TRUE },
526 { CRYPT_OPTION_KEYING_ITERATIONS, "CRYPT_OPTION_KEYING_ITERATIONS", TRUE },
527
528 { CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES, "CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES", TRUE },
529 { CRYPT_OPTION_CERT_VALIDITY, "CRYPT_OPTION_CERT_VALIDITY", TRUE },
530 { CRYPT_OPTION_CERT_UPDATEINTERVAL, "CRYPT_OPTION_CERT_UPDATEINTERVAL", TRUE },
531 { CRYPT_OPTION_CERT_COMPLIANCELEVEL, "CRYPT_OPTION_CERT_COMPLIANCELEVEL", TRUE },
532 { CRYPT_OPTION_CERT_REQUIREPOLICY, "CRYPT_OPTION_CERT_REQUIREPOLICY", TRUE },
533
534 { CRYPT_OPTION_CMS_DEFAULTATTRIBUTES, "CRYPT_OPTION_CMS_DEFAULTATTRIBUTES", TRUE },
535
536 { CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS, "CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS", FALSE },
537 { CRYPT_OPTION_KEYS_LDAP_OBJECTTYPE, "CRYPT_OPTION_KEYS_LDAP_OBJECTTYPE", TRUE },
538 { CRYPT_OPTION_KEYS_LDAP_FILTER, "CRYPT_OPTION_KEYS_LDAP_FILTER", FALSE },
539 { CRYPT_OPTION_KEYS_LDAP_CACERTNAME, "CRYPT_OPTION_KEYS_LDAP_CACERTNAME", FALSE },
540 { CRYPT_OPTION_KEYS_LDAP_CERTNAME, "CRYPT_OPTION_KEYS_LDAP_CERTNAME", FALSE },
541 { CRYPT_OPTION_KEYS_LDAP_CRLNAME, "CRYPT_OPTION_KEYS_LDAP_CRLNAME", FALSE },
542 { CRYPT_OPTION_KEYS_LDAP_EMAILNAME, "CRYPT_OPTION_KEYS_LDAP_EMAILNAME", FALSE },
543
544 { CRYPT_OPTION_DEVICE_PKCS11_DVR01, "CRYPT_OPTION_DEVICE_PKCS11_DVR01", FALSE },
545 { CRYPT_OPTION_DEVICE_PKCS11_DVR02, "CRYPT_OPTION_DEVICE_PKCS11_DVR02", FALSE },
546 { CRYPT_OPTION_DEVICE_PKCS11_DVR03, "CRYPT_OPTION_DEVICE_PKCS11_DVR03", FALSE },
547 { CRYPT_OPTION_DEVICE_PKCS11_DVR04, "CRYPT_OPTION_DEVICE_PKCS11_DVR04", FALSE },
548 { CRYPT_OPTION_DEVICE_PKCS11_DVR05, "CRYPT_OPTION_DEVICE_PKCS11_DVR05", FALSE },
549 { CRYPT_OPTION_DEVICE_PKCS11_HARDWAREONLY, "CRYPT_OPTION_DEVICE_PKCS11_HARDWAREONLY", TRUE },
550
551 { CRYPT_OPTION_NET_SOCKS_SERVER, "CRYPT_OPTION_NET_SOCKS_SERVER", FALSE },
552 { CRYPT_OPTION_NET_SOCKS_USERNAME, "CRYPT_OPTION_NET_SOCKS_USERNAME", FALSE },
553 { CRYPT_OPTION_NET_HTTP_PROXY, "CRYPT_OPTION_NET_HTTP_PROXY", FALSE },
554 { CRYPT_OPTION_NET_CONNECTTIMEOUT, "CRYPT_OPTION_NET_CONNECTTIMEOUT", TRUE },
555 { CRYPT_OPTION_NET_READTIMEOUT, "CRYPT_OPTION_NET_READTIMEOUT", TRUE },
556 { CRYPT_OPTION_NET_WRITETIMEOUT, "CRYPT_OPTION_NET_WRITETIMEOUT", TRUE },
557
558 { CRYPT_OPTION_MISC_ASYNCINIT, "CRYPT_OPTION_MISC_ASYNCINIT", TRUE },
559 { CRYPT_OPTION_MISC_SIDECHANNELPROTECTION, "CRYPT_OPTION_MISC_SIDECHANNELPROTECTION", TRUE },
560
561 { CRYPT_ATTRIBUTE_NONE, NULL, 0 }
562 };
563
564 /* Test the configuration options routines */
565
testConfig(void)566 BOOLEAN testConfig( void )
567 {
568 int i, value, status;
569
570 for( i = 0; configOption[ i ].option != CRYPT_ATTRIBUTE_NONE; i++ )
571 {
572 C_CHR buffer[ 256 ];
573 int length;
574
575 if( configOption[ i ].isNumeric )
576 {
577 status = cryptGetAttribute( CRYPT_UNUSED,
578 configOption[ i ].option, &value );
579 if( cryptStatusError( status ) )
580 {
581 fprintf( outputStream, "%s appears to be "
582 "disabled/unavailable in this build.\n",
583 configOption[ i ].name );
584 continue;
585 }
586 fprintf( outputStream, "%s = %d.\n", configOption[ i ].name,
587 value );
588 continue;
589 }
590 status = cryptGetAttributeString( CRYPT_UNUSED,
591 configOption[ i ].option,
592 buffer, &length );
593 if( cryptStatusError( status ) )
594 {
595 fprintf( outputStream, "%s appears to be disabled/unavailable "
596 "in this build.\n", configOption[ i ].name );
597 continue;
598 }
599 assert( length < 256 );
600 #ifdef UNICODE_STRINGS
601 buffer[ length / sizeof( wchar_t ) ] = TEXT( '\0' );
602 fprintf( outputStream, "%s = %S.\n", configOption[ i ].name,
603 buffer );
604 #else
605 buffer[ length ] = '\0';
606 fprintf( outputStream, "%s = %s.\n", configOption[ i ].name,
607 buffer );
608 #endif /* UNICODE_STRINGS */
609 }
610 printf( "\n" );
611
612 return( TRUE );
613 }
614 #else
615
testConfig(void)616 BOOLEAN testConfig( void )
617 {
618 puts( "Skipping display of config options...\n" );
619 return( TRUE );
620 }
621 #endif /* TEST_CONFIG */
622
623 #ifdef TEST_DEVICE
624
625 /* Test the crypto device routines */
626
testDevice(void)627 BOOLEAN testDevice( void )
628 {
629 int status;
630
631 status = testDevices();
632 if( status == CRYPT_ERROR_NOTAVAIL )
633 {
634 puts( "Handling for crypto devices doesn't appear to be enabled in "
635 "this build of\ncryptlib.\n" );
636 return( TRUE );
637 }
638 if( !status )
639 return( FALSE );
640
641 return( TRUE );
642 }
643 #else
644
testDevice(void)645 BOOLEAN testDevice( void )
646 {
647 fputs( "Skipping test of crypto device routines...\n", outputStream );
648 return( TRUE );
649 }
650 #endif /* TEST_DEVICE */
651
652 /****************************************************************************
653 * *
654 * Test Mid/High-level Functions *
655 * *
656 ****************************************************************************/
657
658 #ifdef TEST_MIDLEVEL
659
660 /* Test the mid-level routines */
661
testMidLevel(void)662 BOOLEAN testMidLevel( void )
663 {
664 if( !testLargeBufferEncrypt() )
665 return( FALSE );
666 if( !testDeriveKey() )
667 return( FALSE );
668 if( !testConventionalExportImport() )
669 return( FALSE );
670 if( cryptStatusOK( cryptQueryCapability( CRYPT_ALGO_HMAC_SHA1, NULL ) ) )
671 {
672 /* Only test the MAC functions of HMAC-SHA1 is enabled */
673 if( !testMACExportImport() )
674 return( FALSE );
675 }
676 if( cryptStatusOK( cryptQueryCapability( CRYPT_ALGO_RSA, NULL ) ) )
677 {
678 /* Only test the PKC functions if RSA is enabled */
679 if( !testKeyExportImport() )
680 return( FALSE );
681 if( !testSignData() )
682 return( FALSE );
683 if( !testKeygen() )
684 return( FALSE );
685 }
686 /* No need for putchar, mid-level functions leave a blank line at end */
687
688 return( TRUE );
689 }
690 #else
691
testMidLevel(void)692 BOOLEAN testMidLevel( void )
693 {
694 puts( "Skipping test of mid-level encryption routines...\n" );
695 return( TRUE );
696 }
697 #endif /* TEST_MIDLEVEL */
698
699 #ifdef TEST_HIGHLEVEL
700
701 /* Test the high-level routines (these are similar to the mid-level routines
702 but rely on things like certificate management to work) */
703
testHighLevel(void)704 BOOLEAN testHighLevel( void )
705 {
706 if( !testKeyExportImportCMS() )
707 return( FALSE );
708 if( !testSignDataCMS() )
709 return( FALSE );
710
711 return( TRUE );
712 }
713 #else
714
testHighLevel(void)715 BOOLEAN testHighLevel( void )
716 {
717 puts( "Skipping test of high-level routines...\n" );
718 return( TRUE );
719 }
720 #endif /* TEST_HIGHLEVEL */
721
722 /****************************************************************************
723 * *
724 * Test Certificates *
725 * *
726 ****************************************************************************/
727
728 #ifdef TEST_CERT
729
730 /* Test the certificate routines */
731
testCert(void)732 BOOLEAN testCert( void )
733 {
734 if( !testBasicCert() )
735 return( FALSE );
736 if( !testCACert() )
737 return( FALSE );
738 if( !testXyzzyCert() )
739 return( FALSE );
740 if( !testTextStringCert() )
741 return( FALSE );
742 if( !testComplexCert() )
743 return( FALSE );
744 if( !testCertExtension() )
745 return( FALSE );
746 if( !testCustomDNCert() )
747 return( FALSE );
748 if( !testSETCert() )
749 return( FALSE );
750 if( !testAttributeCert() )
751 return( FALSE );
752 if( !testCertRequest() )
753 return( FALSE );
754 if( !testComplexCertRequest() )
755 return( FALSE );
756 if( !testCertRequestAttrib() )
757 return( FALSE );
758 if( !testCRMFRequest() )
759 return( FALSE );
760 if( !testComplexCRMFRequest() )
761 return( FALSE );
762 if( !testCRL() )
763 return( FALSE );
764 if( !testComplexCRL() )
765 return( FALSE );
766 if( !testRevRequest() )
767 return( FALSE );
768 if( !testCertChain() )
769 return( FALSE );
770 if( !testCMSAttributes() )
771 return( FALSE );
772 if( !testOCSPReqResp() )
773 return( FALSE );
774 if( !testCertImport() )
775 return( FALSE );
776 if( !testCertImportECC() )
777 return( FALSE );
778 if( !testCertReqImport() )
779 return( FALSE );
780 if( !testCRLImport() )
781 return( FALSE );
782 if( !testCertChainImport() )
783 return( FALSE );
784 if( !testOCSPImport() )
785 return( FALSE );
786 if( !testBase64CertImport() )
787 return( FALSE );
788 if( !testBase64CertChainImport() )
789 return( FALSE );
790 if( !testMiscImport() )
791 return( FALSE );
792 if( !testNonchainCert() )
793 return( FALSE );
794 if( !testCertComplianceLevel() )
795 return( FALSE );
796 if( !testCertChainHandling() )
797 return( FALSE );
798 if( !testPKCS1Padding() )
799 return( FALSE );
800 #if 0 /* This takes a while to run and produces a lot of output that won't
801 be meaningful to anyone other than cryptlib developers so it's
802 disabled by default */
803 if( !testPathProcessing() )
804 return( FALSE );
805 #endif /* 0 */
806
807 return( TRUE );
808 }
809 #else
810
testCert(void)811 BOOLEAN testCert( void )
812 {
813 puts( "Skipping test of certificate routines...\n" );
814 return( TRUE );
815 }
816 #endif /* TEST_CERT */
817
818 #ifdef TEST_CERTPROCESS
819
820 /* Test the certificate processing and CA certificate management
821 functionality. A side-effect of the certificate-management
822 functionality is that the OCSP EE test certificates are written
823 to the test data directory */
824
testCertMgmt(void)825 BOOLEAN testCertMgmt( void )
826 {
827 int status;
828
829 if( !testCertProcess() )
830 return( FALSE );
831 status = testCertManagement();
832 if( status == CRYPT_ERROR_NOTAVAIL )
833 {
834 puts( "Handling for CA certificate stores doesn't appear to be "
835 "enabled in this\nbuild of cryptlib, skipping the test of "
836 "the certificate management routines.\n" );
837 }
838 else
839 {
840 if( !status )
841 return( FALSE );
842 }
843
844 return( TRUE );
845 }
846 #else
847
testCertMgmt(void)848 BOOLEAN testCertMgmt( void )
849 {
850 puts( "Skipping test of certificate handling/CA management...\n" );
851 return( TRUE );
852 }
853 #endif /* TEST_CERTPROCESS */
854
855 /****************************************************************************
856 * *
857 * Test Keysets *
858 * *
859 ****************************************************************************/
860
861 #ifdef TEST_KEYSET
862
863 /* Test the file and database keyset read routines */
864
testKeysetFile(void)865 BOOLEAN testKeysetFile( void )
866 {
867 if( !testGetPGPPublicKey() )
868 return( FALSE );
869 if( !testGetPGPPrivateKey() )
870 return( FALSE );
871 if( !testReadWriteFileKey() )
872 return( FALSE );
873 if( !testReadWriteAltFileKey() )
874 return( FALSE );
875 if( !testReadWritePGPFileKey() )
876 return( FALSE );
877 if( !testImportFileKey() )
878 return( FALSE );
879 if( !testReadFilePublicKey() )
880 return( FALSE );
881 if( !testDeleteFileKey() )
882 return( FALSE );
883 if( !testUpdateFileCert() )
884 return( FALSE );
885 if( !testReadFileCert() )
886 return( FALSE );
887 if( !testReadFileCertPrivkey() )
888 return( FALSE );
889 if( !testWriteFileCertChain() )
890 return( FALSE );
891 if( !testReadFileCertChain() )
892 return( FALSE );
893 if( !testAddTrustedCert() )
894 return( FALSE );
895 #if 0 /* This changes the global config file and is disabled by default */
896 if( !testAddGloballyTrustedCert() )
897 return( FALSE );
898 #endif /* 0 */
899 if( !testWriteFileLongCertChain() )
900 return( FALSE );
901 if( !testSingleStepFileCert() )
902 return( FALSE );
903 if( !testSingleStepAltFileCert() )
904 return( FALSE );
905 if( !testDoubleCertFile() )
906 return( FALSE );
907 if( !testRenewedCertFile() )
908 return( FALSE );
909 if( !testReadAltFileKey() )
910 return( FALSE );
911 if( !testReadMiscFile() )
912 return( FALSE );
913 return( TRUE );
914 }
915
testKeysetDatabase(void)916 BOOLEAN testKeysetDatabase( void )
917 {
918 int status;
919
920 #ifdef DATABASE_AUTOCONFIG
921 checkCreateDatabaseKeysets();
922 #endif /* DATABASE_AUTOCONFIG */
923 status = testWriteCert();
924 if( status == CRYPT_ERROR_NOTAVAIL )
925 {
926 puts( "Handling for certificate databases doesn't appear to be "
927 "enabled in this\nbuild of cryptlib, skipping the test of "
928 "the certificate database routines.\n" );
929 }
930 else
931 {
932 if( status == TRUE )
933 {
934 if( !testReadCert() )
935 return( FALSE );
936 if( !testKeysetQuery() )
937 return( FALSE );
938 }
939 }
940 /* For the following tests we may have read access but not write access,
941 so we test a read of known-present certs before trying a write -
942 unlike the local keysets we don't need to add a certificate before we
943 can try reading it */
944 status = testReadCertLDAP();
945 if( status == CRYPT_ERROR_NOTAVAIL )
946 {
947 puts( "Handling for LDAP certificate directories doesn't appear to "
948 "be enabled in\nthis build of cryptlib, skipping the test of "
949 "the certificate directory\nroutines.\n" );
950 }
951 else
952 {
953 /* LDAP access can fail if the directory doesn't use the standard
954 du jour, so we don't treat a failure as a fatal error */
955 if( status )
956 {
957 /* LDAP writes are even worse than LDAP reads, so we don't
958 treat failures here as fatal either */
959 testWriteCertLDAP();
960 }
961 }
962 status = testReadCertURL();
963 if( status == CRYPT_ERROR_NOTAVAIL )
964 {
965 puts( "Handling for fetching certificates from web pages doesn't "
966 "appear to be\nenabled in this build of cryptlib, skipping "
967 "the test of the HTTP routines.\n" );
968 }
969 else
970 {
971 /* Being able to read a certificate from a web page is rather
972 different from access to an HTTP certificate store so we don't
973 treat an error here as fatal */
974 if( status )
975 testReadCertHTTP();
976 }
977
978 return( TRUE );
979 }
980 #else
981
testKeysetFile(void)982 BOOLEAN testKeysetFile( void )
983 {
984 puts( "Skipping test of file keyset read routines...\n" );
985 return( TRUE );
986 }
987
testKeysetDatabase(void)988 BOOLEAN testKeysetDatabase( void )
989 {
990 puts( "Skipping test of database keyset read routines...\n" );
991 return( TRUE );
992 }
993 #endif /* TEST_KEYSET */
994
995 /****************************************************************************
996 * *
997 * Test Enveloping *
998 * *
999 ****************************************************************************/
1000
1001 #ifdef TEST_ENVELOPE
1002
1003 /* Test the enveloping routines */
1004
testEnveloping(void)1005 BOOLEAN testEnveloping( void )
1006 {
1007 if( !testEnvelopeData() )
1008 return( FALSE );
1009 if( !testEnvelopeDataLargeBuffer() )
1010 return( FALSE );
1011 if( !testEnvelopeCompress() )
1012 return( FALSE );
1013 if( !testPGPEnvelopeCompressedDataImport() )
1014 return( FALSE );
1015 if( !testEnvelopeSessionCrypt() )
1016 return( FALSE );
1017 if( !testEnvelopeSessionCryptLargeBuffer() )
1018 return( FALSE );
1019 if( !testEnvelopeCrypt() )
1020 return( FALSE );
1021 if( !testEnvelopePasswordCrypt() )
1022 return( FALSE );
1023 if( !testEnvelopePasswordCryptBoundary() )
1024 return( FALSE );
1025 if( !testEnvelopePasswordCryptImport() )
1026 return( FALSE );
1027 if( !testPGPEnvelopePasswordCryptImport() )
1028 return( FALSE );
1029 if( !testEnvelopePKCCrypt() )
1030 return( FALSE );
1031 if( !testEnvelopePKCCryptAlgo() )
1032 return( FALSE );
1033 if( !testPGPEnvelopePKCCryptImport() )
1034 return( FALSE );
1035 if( !testEnvelopePKCIterated() )
1036 return( FALSE );
1037 if( !testEnvelopeSign() )
1038 return( FALSE );
1039 if( !testEnvelopeSignAlgos() )
1040 return( FALSE );
1041 if( !testEnvelopeSignHashUpgrade() )
1042 return( FALSE );
1043 if( !testEnvelopeSignOverflow() )
1044 return( FALSE );
1045 if( !testEnvelopeSignIndef() )
1046 return( FALSE );
1047 if( !testPGPEnvelopeSignedDataImport() )
1048 return( FALSE );
1049 if( !testEnvelopeAuthenticate() )
1050 return( FALSE );
1051 if( !testEnvelopeAuthEnc() )
1052 return( FALSE );
1053 if( !testCMSEnvelopePKCCrypt() )
1054 return( FALSE );
1055 if( !testCMSEnvelopePKCCryptDoubleCert() )
1056 return( FALSE );
1057 if( !testCMSEnvelopePKCCryptImport() )
1058 return( FALSE );
1059 if( !testCMSEnvelopeSign() )
1060 return( FALSE );
1061 if( !testCMSEnvelopeDualSign() )
1062 return( FALSE );
1063 if( !testCMSEnvelopeDetachedSig() )
1064 return( FALSE );
1065 if( !testCMSEnvelopeRefCount() )
1066 return( FALSE );
1067 if( !testCMSEnvelopeSignedDataImport() )
1068 return( FALSE );
1069
1070 return( TRUE );
1071 }
1072 #else
1073
testEnveloping(void)1074 BOOLEAN testEnveloping( void )
1075 {
1076 puts( "Skipping test of enveloping routines...\n" );
1077 return( TRUE );
1078 }
1079 #endif /* TEST_ENVELOPE */
1080
1081 /****************************************************************************
1082 * *
1083 * Test Sessions *
1084 * *
1085 ****************************************************************************/
1086
1087 #ifdef TEST_SESSION
1088
1089 /* Test the session routines */
1090
testSessions(void)1091 BOOLEAN testSessions( void )
1092 {
1093 int status;
1094
1095 status = testSessionUrlParse();
1096 if( !status )
1097 return( FALSE );
1098 if( status == CRYPT_ERROR_NOTAVAIL )
1099 {
1100 puts( "Network access doesn't appear to be enabled in this build of "
1101 "cryptlib,\nskipping the test of the secure session routines.\n" );
1102 return( TRUE );
1103 }
1104 if( !checkNetworkAccess() )
1105 {
1106 puts( "Couldn't perform a test connect to a well-known site "
1107 "(Amazon.com) which\nindicates that external network access "
1108 "isn't available. Is this machine\nsituated behind a "
1109 "firewall?\n" );
1110 return( FALSE );
1111 }
1112 if( !testSessionAttributes() )
1113 return( FALSE );
1114 if( !testSessionSSH() )
1115 return( FALSE );
1116 if( !testSessionSSHClientCert() )
1117 return( FALSE );
1118 if( !testSessionSSHPortforward() )
1119 return( FALSE );
1120 if( !testSessionSSHExec() )
1121 return( FALSE );
1122 if( !testSessionSSL() )
1123 return( FALSE );
1124 if( !testSessionSSLLocalSocket() )
1125 return( FALSE );
1126 if( !testSessionTLS() )
1127 return( FALSE );
1128 if( !testSessionTLSLocalSocket() )
1129 return( FALSE );
1130 if( !testSessionTLS11() )
1131 return( FALSE );
1132 if( !testSessionTLS12() )
1133 return( FALSE );
1134 #if 0 /* The MS test server used for the general TLS 1.2 tests requires
1135 fairly extensive custom configuration of client certs and the
1136 ability to do rehandshakes due to the oddball way that schannel
1137 handles client-auth, so we disable this test until another
1138 server that actually does TLS 1.2 client auth appears */
1139 if( !testSessionTLS12ClientCert() )
1140 return( FALSE );
1141 #endif /* 0 */
1142 if( !testSessionOCSP() )
1143 return( FALSE );
1144 if( !testSessionTSP() )
1145 return( FALSE );
1146 if( !testSessionEnvTSP() )
1147 return( FALSE );
1148 if( !testSessionCMP() )
1149 return( FALSE );
1150
1151 return( TRUE );
1152 }
1153 #else
1154
testSessions(void)1155 BOOLEAN testSessions( void )
1156 {
1157 puts( "Skipping test of session routines...\n" );
1158 return( TRUE );
1159 }
1160 #endif /* TEST_SESSION */
1161
1162 #ifdef TEST_SESSION_LOOPBACK
1163
1164 /* Test loopback client/server sessions. These require a threaded OS and
1165 are aliased to no-ops on non-threaded systems. In addition there can be
1166 synchronisation problems between the two threads if the server is delayed
1167 for some reason, resulting in the client waiting for a socket that isn't
1168 opened yet. This isn't easy to fix without a lot of explicit intra-
1169 thread synchronisation, if there's a problem it's easier to just re-run
1170 the tests */
1171
testSessionsLoopback(void)1172 BOOLEAN testSessionsLoopback( void )
1173 {
1174 #ifdef DATABASE_AUTOCONFIG
1175 checkCreateDatabaseKeysets(); /* Needed for PKI tests */
1176 #endif /* DATABASE_AUTOCONFIG */
1177 if( !testSessionSSHClientServer() )
1178 return( FALSE );
1179 if( !testSessionSSHClientServerDsaKey() )
1180 return( FALSE );
1181 if( !testSessionSSHClientServerEccKey() )
1182 return( FALSE );
1183 if( !testSessionSSHClientServerFingerprint() )
1184 return( FALSE );
1185 if( !testSessionSSHClientServerPortForward() )
1186 return( FALSE );
1187 if( !testSessionSSHClientServerExec() )
1188 return( FALSE );
1189 if( !testSessionSSHClientServerMultichannel() )
1190 return( FALSE );
1191 if( !testSessionSSHClientServerDebugCheck() )
1192 return( FALSE );
1193 if( !testSessionSSLClientServer() )
1194 return( FALSE );
1195 if( !testSessionSSLClientCertClientServer() )
1196 return( FALSE );
1197 if( !testSessionTLSClientServer() )
1198 return( FALSE );
1199 if( !testSessionTLSSharedKeyClientServer() )
1200 return( FALSE );
1201 if( !testSessionTLSNoSharedKeyClientServer() )
1202 return( FALSE );
1203 if( !testSessionTLSBulkTransferClientServer() )
1204 return( FALSE );
1205 if( !testSessionTLS11ClientServer() )
1206 return( FALSE );
1207 if( !testSessionTLS11ClientCertClientServer() )
1208 return( FALSE );
1209 if( !testSessionTLS12ClientServer() )
1210 return( FALSE );
1211 if( !testSessionTLS12ClientCertClientServer() )
1212 return( FALSE );
1213 if( !testSessionTLS12ClientCertManualClientServer() )
1214 return( FALSE );
1215 if( !testSessionSSLClientServerDebugCheck() )
1216 return( FALSE );
1217 if( !testSessionHTTPCertstoreClientServer() )
1218 return( FALSE );
1219 if( !testSessionRTCSClientServer() )
1220 return( FALSE );
1221 if( !testSessionOCSPClientServer() )
1222 return( FALSE );
1223 if( !testSessionOCSPMulticertClientServer() )
1224 return( FALSE );
1225 if( !testSessionTSPClientServer() )
1226 return( FALSE );
1227 if( !testSessionTSPClientServerPersistent() )
1228 return( FALSE );
1229 if( !testSessionSCEPClientServer() )
1230 return( FALSE );
1231 if( !testSessionSCEPCACertClientServer() )
1232 return( FALSE );
1233 #if 0 /* Requires changes to the SCEP specification */
1234 if( !testSessionSCEPRenewClientServer() )
1235 return( FALSE );
1236 #endif /* 0 */
1237 if( !testSessionCMPClientServer() )
1238 return( FALSE );
1239 if( !testSessionCMPSHA2ClientServer() )
1240 return( FALSE );
1241 if( !testSessionCMPPKIBootClientServer() )
1242 return( FALSE );
1243 if( !testSessionPNPPKIClientServer() )
1244 return( FALSE );
1245 if( !testSessionPNPPKICAClientServer() )
1246 return( FALSE );
1247 #if 0 /* Full RA functionality not completely implemented yet */
1248 if( !testSessionCMPRAClientServer() )
1249 return( FALSE );
1250 #endif /* 0 */
1251 if( !testSessionCMPFailClientServer() )
1252 return( FALSE );
1253
1254 /* The final set of loopback tests, which spawn a large number of
1255 threads, can be somewhat alarming due to the amount of message spew
1256 that they produce so we only run them on one specific development
1257 test machine */
1258 #if defined( __WINDOWS__ ) && !defined( _WIN32_WCE )
1259 {
1260 char name[ MAX_COMPUTERNAME_LENGTH + 1 ];
1261 int length = MAX_COMPUTERNAME_LENGTH + 1;
1262
1263 if( GetComputerName( name, &length ) && length == 7 && \
1264 !memcmp( name, "WHISPER", length ) && 0 )
1265 {
1266 if( !testSessionSSHClientServerDualThread() )
1267 return( FALSE );
1268 if( !testSessionSSHClientServerMultiThread() )
1269 return( FALSE );
1270 if( !testSessionTLSClientServerMultiThread() )
1271 return( FALSE );
1272 }
1273 }
1274 #endif /* __WINDOWS__ && !WinCE */
1275 return( TRUE );
1276 }
1277 #else
1278
testSessionsLoopback(void)1279 BOOLEAN testSessionsLoopback( void )
1280 {
1281 puts( "Skipping test of session routines...\n" );
1282 return( TRUE );
1283 }
1284 #endif /* TEST_SESSION_LOOPBACK */
1285
1286 /****************************************************************************
1287 * *
1288 * Test Users *
1289 * *
1290 ****************************************************************************/
1291
1292 #ifdef TEST_USER
1293
1294 /* Test the user routines */
1295
testUsers(void)1296 BOOLEAN testUsers( void )
1297 {
1298 if( !testUser() )
1299 return( FALSE );
1300
1301 return( TRUE );
1302 }
1303 #else
1304
testUsers(void)1305 BOOLEAN testUsers( void )
1306 {
1307 puts( "Skipping test of user routines...\n" );
1308 return( TRUE );
1309 }
1310
1311 /****************************************************************************
1312 * *
1313 * Test Memory Fault-injection *
1314 * *
1315 ****************************************************************************/
1316
1317 /* Test error-handling code paths by forcing memory-allocation faults at
1318 every location in which cryptlib allocates memory. Note that this test
1319 can only be run if all of the cryptlib self-tests complete successfully,
1320 since it injects memory faults until the self-tests report success */
1321
1322 /*#define TEST_MEMFAULT /* Undefine to perform memory-fault tests */
1323
1324 #ifdef TEST_MEMFAULT
1325
1326 #if !defined( TEST_SELFTEST ) || !defined( TEST_CERT ) || \
1327 !defined( TEST_HIGHLEVEL )
1328 #error Need to enable all tests for fault-allocation test.
1329 #endif /* Defines to indicate that all tests are enabled */
1330
testInit(void)1331 BOOLEAN testInit( void )
1332 {
1333 int status;
1334
1335 status = cryptInit();
1336 return( cryptStatusError( status ) ? FALSE : TRUE );
1337 }
1338
1339 #define FAULT_STARTFUNCTION 0
1340 #define FAULT_STARTINDEX 0
1341
1342 typedef int ( *FUNCTION_PTR )( void );
1343 typedef struct {
1344 FUNCTION_PTR function;
1345 const char *functionName;
1346 } FUNCTION_TBL;
1347
1348 #define MK_FN( function ) { function, #function }
1349
1350 static const FUNCTION_TBL functionTbl[] = {
1351 MK_FN( testInit ),
1352 MK_FN( testSelfTest ),
1353 MK_FN( testLowLevel ),
1354 MK_FN( testRandom ),
1355 MK_FN( testConfig ),
1356 MK_FN( testDevice ),
1357 MK_FN( testMidLevel ),
1358 MK_FN( testCert ),
1359 MK_FN( testKeysetFile ),
1360 MK_FN( testKeysetDatabase ),
1361 MK_FN( testCertMgmt ),
1362 MK_FN( testHighLevel ),
1363 MK_FN( testEnveloping ),
1364 MK_FN( testSessions ),
1365 MK_FN{ NULL )
1366 };
1367
1368 static void testMemFault( void )
1369 {
1370 int functionIndex;
1371
1372 /* Since we don't want to have tons of diagnostic output interspersed
1373 with the mem-fault output, we redirect the diagnostic output to
1374 /dev/null */
1375 outputStream = fopen( "nul:", "w" );
1376 assert( outputStream != NULL );
1377
1378 puts( "Testing memory fault injection..." );
1379 for( functionIndex = FAULT_STARTFUNCTION;
1380 functionTbl[ functionIndex ].function != NULL;
1381 functionIndex++ )
1382 {
1383 int memFaultIndex;
1384
1385 for( memFaultIndex = FAULT_STARTINDEX; memFaultIndex < 10000;
1386 memFaultIndex++ )
1387 {
1388 int status;
1389
1390 /* If we're testing something other than the cryptInit()
1391 functionality then we need to initialise cryptlib first */
1392 if( functionIndex != 0 )
1393 {
1394 /* Since we've already tested the init functionality, we
1395 don't want to fault the init any more */
1396 cryptSetMemFaultCount( 10000 );
1397 status = cryptInit();
1398 assert( cryptStatusOK( status ) );
1399 }
1400
1401 /* Tell the debug-allocator to return an out-of-memory condition
1402 after the given number of allocations */
1403 printf( "%s: %d.\r", functionTbl[ functionIndex ].functionName,
1404 memFaultIndex );
1405 cryptSetMemFaultCount( memFaultIndex );
1406
1407 /* Call the test function, with a memory fault at the given
1408 memory allocation number */
1409 status = functionTbl[ functionIndex ].function();
1410 if( status != TRUE )
1411 {
1412 if( functionIndex != 0 )
1413 cryptEnd();
1414 continue;
1415 }
1416 cryptEnd();
1417 break;
1418 }
1419 assert( memFaultIndex < 10000 );
1420 putchar( '\n' );
1421 }
1422 }
1423 #endif /* TEST_MEMFAULT */
1424 #endif /* TEST_USER */
1425