]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/sslEcdsa/sslEcdsa.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / sslEcdsa / sslEcdsa.cpp
1 /*
2 * sslEcdsa.cpp - test SSL connections to a number of known servers.
3 *
4 * Note this uses the keychain ecdsa.keychain in cwd; it contains an
5 * SSL client auth identity. To avoid ACL hassles and to allow this
6 * program to run hands-off, the identity is imported into this keychain
7 * with no ACL on the private key. This is done with the kcImport tool
8 * like so:
9 *
10 * % kcImport ecc-secp256r1-client.pfx -k ___path_to_cwd___/ecdsa.keychain -f pkcs12 -z password -n
11 */
12 #include <Security/SecureTransport.h>
13 #include <Security/SecureTransportPriv.h>
14 #include <Security/Security.h>
15 #include <clAppUtils/sslAppUtils.h>
16 #include <clAppUtils/ioSock.h>
17 #include <utilLib/common.h>
18
19 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <time.h>
25 #include <ctype.h>
26 #include <sys/param.h>
27
28 static void usage(char **argv)
29 {
30 printf("Usage: %s [options]\n", argv[0]);
31 printf("options:\n");
32 printf(" -t testNum -- only do test testNum; default is all\n");
33 printf(" -q -- quiet\n");
34 printf(" -b -- non blocking I/O\n");
35 printf(" -p -- pause for malloc debug\n");
36 exit(1);
37 }
38
39 #define IGNORE_SIGPIPE 1
40 #if IGNORE_SIGPIPE
41 #include <signal.h>
42
43 void sigpipe(int sig)
44 {
45 }
46 #endif /* IGNORE_SIGPIPE */
47
48 /* Test params */
49 typedef struct {
50 const char *hostName;
51 int port;
52
53 /* We enable exacly one CipherSuite and require that to work */
54 SSLCipherSuite cipherSuite;
55
56 /* Curve to specify; SSL_Curve_None means use default */
57 SSL_ECDSA_NamedCurve specCurve;
58
59 /* Curve to verify; SSL_Curve_None means don't check */
60 SSL_ECDSA_NamedCurve expCurve;
61
62 /*
63 * keychain containing client-side cert, located in LOCAL_BUILD_DIR.
64 * NULL means no keychain.
65 */
66 const char *keychain;
67
68 /* password for above keychain */
69 const char *kcPassword;
70 } EcdsaTestParams;
71
72 static const EcdsaTestParams ecdsaTestParams[] =
73 {
74 /* client auth */
75 {
76 "tls.secg.org", 8443, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
77 SSL_Curve_None, SSL_Curve_None,
78 "ecdsa.keychain", "password"
79 },
80 /* tla.secg.org -- port 40023 - secp256r1 */
81 {
82 "tls.secg.org", 40023, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
83 SSL_Curve_None, SSL_Curve_secp256r1
84 },
85 {
86 "tls.secg.org", 40023, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
87 SSL_Curve_secp256r1, SSL_Curve_secp256r1
88 },
89 {
90 "tls.secg.org", 40023, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
91 SSL_Curve_None, SSL_Curve_secp256r1
92 },
93 {
94 "tls.secg.org", 40023, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
95 SSL_Curve_None, SSL_Curve_secp256r1
96 },
97 {
98 "tls.secg.org", 40023, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
99 SSL_Curve_None, SSL_Curve_secp256r1
100 },
101 {
102 "tls.secg.org", 40023, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
103 SSL_Curve_None, SSL_Curve_secp256r1
104 },
105 {
106 "tls.secg.org", 40023, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
107 SSL_Curve_None, SSL_Curve_secp256r1
108 },
109 {
110 "tls.secg.org", 40023, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
111 SSL_Curve_secp256r1, SSL_Curve_secp256r1
112 },
113 {
114 "tls.secg.org", 40023, TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
115 SSL_Curve_None, SSL_Curve_secp256r1
116 },
117 {
118 "tls.secg.org", 40023, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
119 SSL_Curve_None, SSL_Curve_secp256r1
120 },
121 {
122 "tls.secg.org", 40023, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
123 SSL_Curve_secp256r1, SSL_Curve_secp256r1
124 },
125
126 /* tla.secg.org -- port 40024 - secp384r1 */
127 /* This one doesn't let you specify a curve */
128 {
129 "tls.secg.org", 40024, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
130 SSL_Curve_None, SSL_Curve_secp384r1
131 },
132 {
133 "tls.secg.org", 40024, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
134 SSL_Curve_None, SSL_Curve_secp384r1
135 },
136 {
137 "tls.secg.org", 40024, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
138 SSL_Curve_None, SSL_Curve_secp384r1
139 },
140 {
141 "tls.secg.org", 40024, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
142 SSL_Curve_None, SSL_Curve_secp384r1
143 },
144 {
145 "tls.secg.org", 40024, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
146 SSL_Curve_None, SSL_Curve_secp384r1
147 },
148 {
149 "tls.secg.org", 40024, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
150 SSL_Curve_None, SSL_Curve_secp384r1
151 },
152 {
153 "tls.secg.org", 40024, TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
154 SSL_Curve_None, SSL_Curve_secp384r1
155 },
156 {
157 "tls.secg.org", 40024, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
158 SSL_Curve_None, SSL_Curve_secp384r1
159 },
160
161 /* tla.secg.org -- port 40025 - secp521r1 */
162 {
163 "tls.secg.org", 40025, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
164 SSL_Curve_None, SSL_Curve_secp521r1
165 },
166 {
167 "tls.secg.org", 40025, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
168 SSL_Curve_None, SSL_Curve_secp521r1
169 },
170 {
171 "tls.secg.org", 40025, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
172 SSL_Curve_None, SSL_Curve_secp521r1
173 },
174 {
175 "tls.secg.org", 40025, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
176 SSL_Curve_None, SSL_Curve_secp521r1
177 },
178 {
179 "tls.secg.org", 40025, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
180 SSL_Curve_None, SSL_Curve_secp521r1
181 },
182 {
183 "tls.secg.org", 40025, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
184 SSL_Curve_None, SSL_Curve_secp521r1
185 },
186 {
187 "tls.secg.org", 40025, TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
188 SSL_Curve_None, SSL_Curve_secp521r1
189 },
190 {
191 "tls.secg.org", 40025, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
192 SSL_Curve_None, SSL_Curve_secp521r1
193 },
194
195
196 /* ecc.fedora.redhat.com - port 8443 - secp256r1 */
197 {
198 "ecc.fedora.redhat.com", 8443, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
199 SSL_Curve_None, SSL_Curve_secp256r1
200 },
201 {
202 "ecc.fedora.redhat.com", 8443, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
203 SSL_Curve_secp256r1, SSL_Curve_secp256r1
204 },
205 {
206 "ecc.fedora.redhat.com", 8443, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
207 SSL_Curve_None, SSL_Curve_secp256r1
208 },
209 {
210 "ecc.fedora.redhat.com", 8443, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
211 SSL_Curve_secp256r1, SSL_Curve_secp256r1
212 },
213 {
214 "ecc.fedora.redhat.com", 8443, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
215 SSL_Curve_secp256r1, SSL_Curve_secp256r1
216 },
217 {
218 "ecc.fedora.redhat.com", 8443, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
219 SSL_Curve_None, SSL_Curve_secp256r1
220 },
221 {
222 "ecc.fedora.redhat.com", 8443, TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
223 SSL_Curve_secp256r1, SSL_Curve_secp256r1
224 },
225 {
226 "ecc.fedora.redhat.com", 8443, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
227 SSL_Curve_secp256r1, SSL_Curve_secp256r1
228 },
229
230 /* ecc.fedora.redhat.com - port 8444 - SSL_Curve_secp384r1 */
231 /* This doesn't work, the server requires a redirect ...
232 {
233 "ecc.fedora.redhat.com", 8444, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
234 SSL_Curve_None, SSL_Curve_secp384r1
235 },
236 */
237 {
238 "ecc.fedora.redhat.com", 8445, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
239 SSL_Curve_None, SSL_Curve_secp521r1
240 },
241 {
242 "ecc.fedora.redhat.com", 8444, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
243 SSL_Curve_secp384r1, SSL_Curve_secp384r1
244 },
245 {
246 "ecc.fedora.redhat.com", 8444, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
247 SSL_Curve_secp384r1, SSL_Curve_secp384r1
248 },
249 {
250 "ecc.fedora.redhat.com", 8444, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
251 SSL_Curve_None, SSL_Curve_secp384r1
252 },
253 {
254 "ecc.fedora.redhat.com", 8444, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
255 SSL_Curve_None, SSL_Curve_secp384r1
256 },
257 {
258 "ecc.fedora.redhat.com", 8444, TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
259 SSL_Curve_secp384r1, SSL_Curve_secp384r1
260 },
261 {
262 "ecc.fedora.redhat.com", 8444, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
263 SSL_Curve_secp384r1, SSL_Curve_secp384r1
264 },
265
266 /* ecc.fedora.redhat.com - port 8445 - SSL_Curve_secp521r1 */
267 /* This one can't do RC4_128 without some HTTP redirection */
268 {
269 "ecc.fedora.redhat.com", 8445, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
270 SSL_Curve_None, SSL_Curve_secp521r1
271 },
272 {
273 "ecc.fedora.redhat.com", 8445, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
274 SSL_Curve_secp521r1, SSL_Curve_secp521r1
275 },
276 {
277 "ecc.fedora.redhat.com", 8445, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
278 SSL_Curve_secp521r1, SSL_Curve_secp521r1
279 },
280
281 /* ecc.fedora.redhat.com - port 443 - secp256r1 with RSA authentication */
282 {
283 "ecc.fedora.redhat.com", 443, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
284 SSL_Curve_secp256r1, SSL_Curve_secp256r1
285 },
286 {
287 "ecc.fedora.redhat.com", 443, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
288 SSL_Curve_secp256r1, SSL_Curve_secp256r1
289 },
290 {
291 "ecc.fedora.redhat.com", 443, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
292 SSL_Curve_secp256r1, SSL_Curve_secp256r1
293 },
294 {
295 "ecc.fedora.redhat.com", 443, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
296 SSL_Curve_secp256r1, SSL_Curve_secp256r1
297 },
298 {
299 "ecc.fedora.redhat.com", 443, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
300 SSL_Curve_None, SSL_Curve_secp256r1
301 },
302 {
303 "ecc.fedora.redhat.com", 443, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
304 SSL_Curve_secp256r1, SSL_Curve_secp256r1
305 },
306 {
307 "ecc.fedora.redhat.com", 443, TLS_ECDH_RSA_WITH_RC4_128_SHA,
308 SSL_Curve_None, SSL_Curve_secp256r1
309 },
310 {
311 "ecc.fedora.redhat.com", 443, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
312 SSL_Curve_None, SSL_Curve_secp256r1
313 },
314
315 /* etc. */
316 };
317 #define NUM_TEST_PARAMS (sizeof(ecdsaTestParams) / sizeof(ecdsaTestParams[0]))
318
319 static void dumpParams(
320 const EcdsaTestParams *testParams)
321 {
322 printf("%s:%d %-33s ",
323 testParams->hostName, testParams->port,
324 /* skip leading "TLS_" */
325 sslGetCipherSuiteString(testParams->cipherSuite)+4);
326 if(testParams->expCurve != SSL_Curve_None) {
327 printf("expCurve = %s ", sslCurveString(testParams->expCurve));
328 }
329 if(testParams->specCurve != SSL_Curve_None) {
330 printf("specCurve = %s ", sslCurveString(testParams->specCurve));
331 }
332 if(testParams->keychain) {
333 printf("Client Auth Enabled");
334 }
335 putchar('\n');
336 }
337
338 static void dumpErrInfo(
339 const char *op,
340 const EcdsaTestParams *testParams,
341 OSStatus ortn)
342 {
343 printf("***%s failed for ", op);
344 dumpParams(testParams);
345 printf(" error: %s\n", sslGetSSLErrString(ortn));
346 }
347
348 /*
349 * Custom ping for this test.
350 */
351 #define RCV_BUF_SIZE 256
352
353 static int doSslPing(
354 const EcdsaTestParams *testParams,
355 bool quiet,
356 int nonBlocking)
357 {
358 PeerSpec peerId;
359 otSocket sock = 0;
360 OSStatus ortn;
361 SSLContextRef ctx = NULL;
362 SSLCipherSuite negCipher;
363
364 /* first make sure requested server is there */
365 ortn = MakeServerConnection(testParams->hostName, testParams->port,
366 nonBlocking, &sock, &peerId);
367 if(ortn) {
368 printf("MakeServerConnection(%s) returned %d\n",
369 testParams->hostName, (int)ortn);
370 return -1;
371 }
372
373 /*
374 * Set up a SecureTransport session.
375 * First the standard calls.
376 */
377 ortn = SSLNewContext(false, &ctx);
378 if(ortn) {
379 printSslErrStr("SSLNewContext", ortn);
380 goto cleanup;
381 }
382 ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite);
383 if(ortn) {
384 printSslErrStr("SSLSetIOFuncs", ortn);
385 goto cleanup;
386 }
387
388 /* Restrict to only TLSv1 - we have to do this because of Radar 6133465 */
389 ortn = SSLSetProtocolVersionEnabled(ctx, kSSLProtocolAll, false);
390 if(ortn) {
391 printSslErrStr("SSLSetProtocolVersionEnabled", ortn);
392 goto cleanup;
393 }
394 ortn = SSLSetProtocolVersionEnabled(ctx, kTLSProtocol1, true);
395 if(ortn) {
396 printSslErrStr("SSLSetProtocolVersionEnabled", ortn);
397 goto cleanup;
398 }
399
400 /* Restrict to only one CipherSuite */
401 ortn = SSLSetEnabledCiphers(ctx, &testParams->cipherSuite, 1);
402 if(ortn) {
403 printSslErrStr("SSLSetEnabledCiphers", ortn);
404 goto cleanup;
405 }
406
407 ortn = SSLSetConnection(ctx, (SSLConnectionRef)sock);
408 if(ortn) {
409 printSslErrStr("SSLSetConnection", ortn);
410 goto cleanup;
411 }
412
413 /* These test servers have custom roots, just allow any roots for this test */
414 ortn = SSLSetAllowsExpiredCerts(ctx, true);
415 if(ortn) {
416 printSslErrStr("SSLSetAllowExpiredCerts", ortn);
417 goto cleanup;
418 }
419 ortn = SSLSetAllowsAnyRoot(ctx, true);
420 if(ortn) {
421 printSslErrStr("SSLSetAllowAnyRoot", ortn);
422 goto cleanup;
423 }
424
425 if(testParams->specCurve != SSL_Curve_None) {
426 ortn = SSLSetECDSACurves(ctx, &testParams->specCurve, 1);
427 if(ortn) {
428 printSslErrStr("SSLSetAllowAnyRoot", ortn);
429 goto cleanup;
430 }
431 }
432
433 if(testParams->keychain) {
434 char kcPath[2000];
435 const char *lbd = getenv("LOCAL_BUILD_DIR");
436 if(lbd == NULL) {
437 printf("WARNING: no LOCAL_BUILD_DIR env var faound\n");
438 lbd = "";
439 }
440 snprintf(kcPath, 2000, "%s/%s", lbd, testParams->keychain);
441 SecKeychainRef kcRef = NULL;
442 CFArrayRef certArray = getSslCerts(kcPath,
443 CSSM_FALSE, // encryptOnly
444 CSSM_FALSE, // completeCertChain
445 NULL, // anchorFile
446 &kcRef);
447 if(kcRef) {
448 /* Unlock it */
449 ortn = SecKeychainUnlock(kcRef,
450 strlen(testParams->kcPassword), testParams->kcPassword,
451 true);
452 if(ortn) {
453 cssmPerror("SecKeychainUnlock", ortn);
454 /* oh well */
455 }
456 CFRelease(kcRef);
457 }
458 if(certArray == NULL) {
459 printf("***WARNING no keychain found at %s\n", kcPath);
460 }
461 ortn = SSLSetCertificate(ctx, certArray);
462 if(ortn) {
463 printSslErrStr("SSLSetAllowAnyRoot", ortn);
464 goto cleanup;
465 }
466 CFRelease(certArray);
467 }
468 do {
469 ortn = SSLHandshake(ctx);
470 } while (ortn == errSSLWouldBlock);
471
472 /* convert normal "shutdown" into zero err rtn */
473 switch(ortn) {
474 case noErr:
475 break;
476 case errSSLClosedGraceful:
477 case errSSLClosedNoNotify:
478 ortn = noErr;
479 break;
480 default:
481 dumpErrInfo("SSLHandshake", testParams, ortn);
482 goto cleanup;
483 }
484
485
486 /*
487 * Unlike other ping tests we don't bother with a GET - just validate
488 * the handshake
489 */
490 ortn = SSLGetNegotiatedCipher(ctx, &negCipher);
491 if(ortn) {
492 dumpErrInfo("SSLHandshake", testParams, ortn);
493 goto cleanup;
494 }
495
496 /* here is really what we're testing */
497 if(negCipher != testParams->cipherSuite) {
498 printf("***Cipher mismatch for ");
499 dumpParams(testParams);
500 printf("Negotiated cipher: %s\n", sslGetCipherSuiteString(negCipher));
501 ortn = ioErr;
502 goto cleanup;
503 }
504 if(testParams->expCurve != SSL_Curve_None) {
505 SSL_ECDSA_NamedCurve actNegCurve;
506 ortn = SSLGetNegotiatedCurve(ctx, &actNegCurve);
507 if(ortn) {
508 printSslErrStr("SSLGetNegotiatedCurve", ortn);
509 goto cleanup;
510 }
511 if(actNegCurve != testParams->expCurve) {
512 printf("***Negotiated curve error\n");
513 printf("Specified curve: %s\n", sslCurveString(testParams->specCurve));
514 printf("Expected curve: %s\n", sslCurveString(testParams->expCurve));
515 printf("Obtained curve: %s\n", sslCurveString(actNegCurve));
516 ortn = ioErr;
517 goto cleanup;
518 }
519 }
520 if(testParams->keychain) {
521 /* Verify client auth */
522 SSLClientCertificateState authState;
523 ortn = SSLGetClientCertificateState(ctx, &authState);
524 if(ortn) {
525 printSslErrStr("SSLGetClientCertificateState", ortn);
526 goto cleanup;
527 }
528 if(authState != kSSLClientCertSent) {
529 printf("***Unexpected ClientCertificateState\n");
530 printf(" Expected: ClientCertSent\n");
531 printf(" Received: %s\n", sslGetClientCertStateString(authState));
532 ortn = ioErr;
533 goto cleanup;
534 }
535 }
536
537 ortn = SSLClose(ctx);
538
539 cleanup:
540 if(sock) {
541 endpointShutdown(sock);
542 }
543 if(ctx) {
544 SSLDisposeContext(ctx);
545 }
546 return (int)ortn;
547 }
548
549
550 int main(int argc, char **argv)
551 {
552 int ourRtn = 0;
553 bool quiet = false;
554 int nonBlocking = false;
555 unsigned minDex = 0;
556 unsigned maxDex = NUM_TEST_PARAMS-1;
557 bool doPause = false;
558
559 extern char *optarg;
560 int arg;
561 while ((arg = getopt(argc, argv, "t:bpqh")) != -1) {
562 switch (arg) {
563 case 't':
564 minDex = maxDex = atoi(optarg);
565 if(minDex > (NUM_TEST_PARAMS - 1)) {
566 printf("***max test number is %u.\n", (unsigned)NUM_TEST_PARAMS);
567 exit(1);
568 }
569 break;
570 case 'q':
571 quiet = true;
572 break;
573 case 'b':
574 nonBlocking = true;
575 break;
576 case 'p':
577 doPause = true;
578 break;
579 default:
580 usage(argv);
581 }
582 }
583 if(optind != argc) {
584 usage(argv);
585 }
586
587 #if IGNORE_SIGPIPE
588 signal(SIGPIPE, sigpipe);
589 #endif
590
591 testStartBanner("sslEcdsa", argc, argv);
592
593 if(doPause) {
594 fpurge(stdin);
595 printf("Pausing at top of loop; CR to continue: ");
596 fflush(stdout);
597 getchar();
598 }
599
600 for(unsigned dex=minDex; dex<=maxDex; dex++) {
601 const EcdsaTestParams *testParams = &ecdsaTestParams[dex];
602 if(!quiet) {
603 printf("[%u]: ", dex);
604 dumpParams(testParams);
605 }
606 ourRtn = doSslPing(testParams, quiet, nonBlocking);
607 if(ourRtn) {
608 if(testError(quiet)) {
609 break;
610 }
611 }
612 }
613
614 if(doPause) {
615 fpurge(stdin);
616 printf("Pausing at end of loop; CR to continue: ");
617 fflush(stdout);
618 getchar();
619 }
620
621 if(!quiet) {
622 if(ourRtn == 0) {
623 printf("===== sslEcdsa test PASSED =====\n");
624 }
625 else {
626 printf("****sslEcdsa test FAILED\n");
627 }
628 }
629
630 return ourRtn;
631 }