2 * Trivial SSL server example, SecureTransport / OS X version.
4 * Written by Doug Mitchell.
6 #include <Security/SecureTransport.h>
7 #include <Security/SecureTransportPriv.h>
8 #include <clAppUtils/sslAppUtils.h>
9 #include <clAppUtils/ioSock.h>
10 #include <clAppUtils/identPicker.h>
11 #include <utilLib/fileIo.h>
12 #include <utilLib/common.h>
13 #include <security_cdsa_utils/cuPrintCert.h>
15 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
21 #include <sys/param.h>
23 #include <Security/Security.h>
25 /* Set true when PR-3074739 is merged to TOT */
26 #define SET_DH_PARAMS_ENABLE 1
28 /* true when using SSLCopyPeerCertificates() per Radar 3311892 */
29 #define USE_COPY_PEER_CERTS 1
32 * Defaults, overridable by user.
34 #define SERVER_MESSAGE "HTTP/1.0 200 OK\015\012Content-Type: text/html\015\012\015\012" \
35 "<HTML><HEAD><TITLE>SecureTransport Test Server</TITLE></HEAD>" \
36 "<BODY><H2>Secure connection established.</H2>" \
37 "Message from the 'sslServer' sample application.\015\012</BODY>" \
40 /* For ease of debugging, pick a non-privileged port */
41 #define DEFAULT_PORT 1200
42 // #define DEFAULT_PORT 443
44 #define DEFAULT_HOST "localhost"
46 #define DEFAULT_KC "certkc"
49 * IE (5.0 on OS9, 5.1.3 on OS X) have an interesting way of handling unrecognized
50 * server certs. Upon receipt of the server cert msg with an unrecognized cert,
51 * IE immediately closes the connection, asks the user of they want to proceed
52 * after the usual dire warning, and retries the whole op from scratch if
53 * so authorized. Unfortunately this is often seen at this end as a broken
54 * pipe when writing either the server cert or the server hello done msg which follows
55 * it. We really have to handle the sigpipe so the lower-level I/O code
56 * (in ioSock.c) can see the error on the write and cleanup. If we don't handle
57 * the signal our process dies.
59 #define IGNORE_SIGPIPE 1
66 printf("***SIGPIPE***\n");
70 static void usage(char **argv
)
72 printf("Usage: %s [option ...]\n", argv
[0]);
74 printf(" P=port Port to listen on; default is %d\n", DEFAULT_PORT
);
75 printf(" k=keychain Contains server cert and keys.\n");
76 printf(" y=keychain Encryption-only cert and keys.\n");
77 printf(" e Allow Expired Certs\n");
78 printf(" r Allow any root cert\n");
79 printf(" E Allow Expired Roots\n");
80 printf(" x Disable Cert Verification\n");
81 printf(" f=fileBase Write Peer Certs to fileBase*\n");
82 printf(" c Display peer certs\n");
83 printf(" d Display received data\n");
84 printf(" C=cipherSuite (e=40-bit d=DES D=40-bit DES 3=3DES 4=RC4 $=40-bit RC4\n"
85 " 2=RC2 a=AES128 A=AES256 h=DH H=Anon DH r=DHE/RSA s=DH/DSS\n"
87 printf(" 2 SSLv2 only (default is best fit)\n");
88 printf(" 3 SSLv3 only (default is best fit)\n");
89 printf(" t TLSv1 only (default is best fit)\n");
90 printf(" o TLSv1, SSLv3 use kSSLProtocol__X__Only\n");
91 printf(" g={prot...} Specify legal protocols; prot = any combo of [23t]\n");
92 printf(" T=[nrsj] Verify client cert state = "
93 "none/requested/sent/rejected\n");
94 printf(" R Disable resumable session support\n");
95 printf(" i=timeout Session cache timeout\n");
96 printf(" u=[nat] Authentication: n=never; a=always; t=try\n");
97 printf(" b Non-blocking I/O\n");
98 printf(" a fileNmae Add fileName to list of trusted roots\n");
99 printf(" A fileName fileName is ONLY trusted root\n");
100 printf(" U filename Add filename to acceptable DNList (multiple times OK)\n");
101 printf(" D filename Diffie-Hellman parameters from filename\n");
102 printf(" z=password Unlock server keychain with password.\n");
103 printf(" H Do SecIndentityRef search instead of specific keychain\n");
104 printf(" M Complete cert chain (default assumes that our identity is root)\n");
105 printf(" 4 Disable anonymous ciphers\n");
106 printf(" p Pause after each phase\n");
107 printf(" l[=loops] Loop, performing multiple transactions\n");
108 printf(" q Quiet/diagnostic mode (site names and errors only)\n");
113 /* snag a copy of current connection's peer certs so we can
114 * examine them later after the connection is closed */
115 static OSStatus
copyPeerCerts(
117 CFArrayRef
*peerCerts
) // mallocd & RETURNED
119 #if USE_COPY_PEER_CERTS
120 OSStatus ortn
= SSLCopyPeerCertificates(ctx
, peerCerts
);
122 OSStatus ortn
= SSLGetPeerCertificates(ctx
, peerCerts
);
125 printf("***Error obtaining peer certs: %s\n",
126 sslGetSSLErrString(ortn
));
131 /* free the cert array obtained via SSLGetPeerCertificates() */
132 static void freePeerCerts(
133 CFArrayRef peerCerts
)
135 if(peerCerts
== NULL
) {
139 #if USE_COPY_PEER_CERTS
141 /* Voila! Problem fixed. */
142 CFRelease(peerCerts
);
148 SecCertificateRef certData
;
151 numCerts
= CFArrayGetCount(peerCerts
);
152 for(i
=0; i
<numCerts
; i
++) {
153 certData
= (SecCertificateRef
)CFArrayGetValueAtIndex(peerCerts
, i
);
156 CFRelease(peerCerts
);
160 /* print reply received from server */
161 static void dumpAscii(
165 char *cp
= (char *)rcvBuf
;
169 for(i
=0; i
<len
; i
++) {
182 if(isprint(c
) && (c
!= '\n')) {
186 printf("<%02X>", ((unsigned)c
) & 0xff);
195 static void doPause(const char *prompt
) {
197 printf("%s. ", prompt
);
200 printf("Continue (n/anything)? ");
208 * Perform one SSL diagnostic server-side session. Returns nonzero on error.
209 * Normally no output to stdout except initial "waiting for connection" message,
210 * unless there is a really screwed up error (i.e., something not directly related
211 * to the SSL connection).
213 #define RCV_BUF_SIZE 256
215 static OSStatus
sslServe(
217 unsigned short portNum
,
218 SSLProtocol tryVersion
, // only used if acceptedProts NULL
219 const char *acceptedProts
,
220 CFArrayRef serverCerts
, // required
221 char *password
, // optional
222 CFArrayRef encryptServerCerts
, // optional
223 CSSM_BOOL allowExpired
,
224 CSSM_BOOL allowAnyRoot
,
225 CSSM_BOOL allowExpiredRoot
,
226 CSSM_BOOL disableCertVerify
,
228 CSSM_BOOL replaceAnchors
,
229 char cipherRestrict
, // '2', 'd'. etc...'\0' for no
231 SSLAuthenticate authenticate
,
232 unsigned char *dhParams
, // optional D-H parameters
233 unsigned dhParamsLen
,
234 CFArrayRef acceptableDNList
, // optional
235 CSSM_BOOL resumableEnable
,
236 uint32 sessionCacheTimeout
,// optional
237 CSSM_BOOL disableAnonCiphers
,
238 CSSM_BOOL silent
, // no stdout
240 SSLProtocol
*negVersion
, // RETURNED
241 SSLCipherSuite
*negCipher
, // RETURNED
242 SSLClientCertificateState
*certState
, // RETURNED
243 Boolean
*sessionWasResumed
, // RETURNED
244 unsigned char *sessionID
, // mallocd by caller, RETURNED
245 size_t *sessionIDLength
, // RETURNED
246 CFArrayRef
*peerCerts
, // mallocd & RETURNED
252 SSLContextRef ctx
= NULL
;
254 uint8 rcvBuf
[RCV_BUF_SIZE
];
255 char *outMsg
= (char *)SERVER_MESSAGE
;
257 *negVersion
= kSSLProtocolUnknown
;
258 *negCipher
= SSL_NULL_WITH_NULL_NULL
;
262 signal(SIGPIPE
, sigpipe
);
265 /* first wait for a connection */
267 printf("Waiting for client connection on port %u...", portNum
);
270 ortn
= AcceptClientConnection(listenSock
, &acceptSock
, &peerId
);
272 printf("AcceptClientConnection returned %d; aborting\n", (int)ortn
);
277 * Set up a SecureTransport session.
278 * First the standard calls.
280 ortn
= SSLNewContext(true, &ctx
);
282 printSslErrStr("SSLNewContext", ortn
);
285 ortn
= SSLSetIOFuncs(ctx
, SocketRead
, SocketWrite
);
287 printSslErrStr("SSLSetIOFuncs", ortn
);
290 ortn
= SSLSetConnection(ctx
, (SSLConnectionRef
)acceptSock
);
292 printSslErrStr("SSLSetConnection", ortn
);
296 /* have to do these options befor setting server certs */
298 ortn
= SSLSetAllowsExpiredCerts(ctx
, true);
300 printSslErrStr("SSLSetAllowExpiredCerts", ortn
);
305 ortn
= SSLSetAllowsAnyRoot(ctx
, true);
307 printSslErrStr("SSLSetAllowAnyRoot", ortn
);
313 ortn
= sslAddTrustedRoot(ctx
, anchorFile
, replaceAnchors
);
315 printf("***Error obtaining anchor file %s\n", anchorFile
);
319 if(serverCerts
!= NULL
) {
320 if(anchorFile
== NULL
) {
321 /* no specific anchors, so assume we want to trust this one */
322 ortn
= addIdentityAsTrustedRoot(ctx
, serverCerts
);
327 ortn
= SSLSetCertificate(ctx
, serverCerts
);
329 printSslErrStr("SSLSetCertificate", ortn
);
333 if(encryptServerCerts
) {
334 ortn
= SSLSetEncryptionCertificate(ctx
, encryptServerCerts
);
336 printSslErrStr("SSLSetEncryptionCertificate", ortn
);
340 if(allowExpiredRoot
) {
341 ortn
= SSLSetAllowsExpiredRoots(ctx
, true);
343 printSslErrStr("SSLSetAllowsExpiredRoots", ortn
);
347 if(disableCertVerify
) {
348 ortn
= SSLSetEnableCertVerify(ctx
, false);
350 printSslErrStr("SSLSetEnableCertVerify", ortn
);
356 * SecureTransport options.
359 ortn
= SSLSetProtocolVersionEnabled(ctx
, kSSLProtocolAll
, false);
361 printSslErrStr("SSLSetProtocolVersionEnabled(all off)", ortn
);
364 for(const char *cp
= acceptedProts
; *cp
; cp
++) {
368 prot
= kSSLProtocol2
;
371 prot
= kSSLProtocol3
;
374 prot
= kTLSProtocol1
;
379 ortn
= SSLSetProtocolVersionEnabled(ctx
, prot
, true);
381 printSslErrStr("SSLSetProtocolVersionEnabled", ortn
);
387 ortn
= SSLSetProtocolVersion(ctx
, tryVersion
);
389 printSslErrStr("SSLSetProtocolVersion", ortn
);
393 if(resumableEnable
) {
394 ortn
= SSLSetPeerID(ctx
, &peerId
, sizeof(PeerSpec
));
396 printSslErrStr("SSLSetPeerID", ortn
);
400 if(cipherRestrict
!= '\0') {
401 ortn
= sslSetCipherRestrictions(ctx
, cipherRestrict
);
406 if(authenticate
!= kNeverAuthenticate
) {
407 ortn
= SSLSetClientSideAuthenticate(ctx
, authenticate
);
409 printSslErrStr("SSLSetClientSideAuthenticate", ortn
);
414 ortn
= SSLSetDiffieHellmanParams(ctx
, dhParams
, dhParamsLen
);
416 printSslErrStr("SSLSetDiffieHellmanParams", ortn
);
420 if(sessionCacheTimeout
) {
421 ortn
= SSLSetSessionCacheTimeout(ctx
, sessionCacheTimeout
);
423 printSslErrStr("SSLSetSessionCacheTimeout", ortn
);
427 if(disableAnonCiphers
) {
428 ortn
= SSLSetAllowAnonymousCiphers(ctx
, false);
430 printSslErrStr("SSLSetAllowAnonymousCiphers", ortn
);
433 /* quickie test of the getter */
435 ortn
= SSLGetAllowAnonymousCiphers(ctx
, &e
);
437 printSslErrStr("SSLGetAllowAnonymousCiphers", ortn
);
441 printf("***SSLGetAllowAnonymousCiphers() returned true; expected false\n");
446 if(acceptableDNList
) {
447 ortn
= SSLSetCertificateAuthorities(ctx
, acceptableDNList
, TRUE
);
449 printSslErrStr("SSLSetCertificateAuthorities", ortn
);
457 doPause("SSLContext initialized");
460 /* Perform SSL/TLS handshake */
462 { ortn
= SSLHandshake(ctx
);
463 if((ortn
== errSSLWouldBlock
) && !silent
) {
464 /* keep UI responsive */
467 } while (ortn
== errSSLWouldBlock
);
469 /* this works even if handshake failed due to cert chain invalid */
470 copyPeerCerts(ctx
, peerCerts
);
472 SSLGetClientCertificateState(ctx
, certState
);
473 SSLGetNegotiatedCipher(ctx
, negCipher
);
474 SSLGetNegotiatedProtocolVersion(ctx
, negVersion
);
475 *sessionIDLength
= MAX_SESSION_ID_LENGTH
;
476 SSLGetResumableSessionInfo(ctx
, sessionWasResumed
, sessionID
,
486 doPause("SSLContext handshake complete");
489 /* wait for one complete line or user says they've had enough */
490 while(ortn
== noErr
) {
491 length
= sizeof(rcvBuf
);
492 ortn
= SSLRead(ctx
, rcvBuf
, length
, &length
);
494 /* keep UI responsive */
498 /* print what we have */
499 printf("client request: ");
500 dumpAscii(rcvBuf
, length
);
503 /* allow user to bail */
507 printf("\nMore client request (y/anything): ");
514 /* poor person's line completion scan */
515 for(unsigned i
=0; i
<length
; i
++) {
516 if((rcvBuf
[i
] == '\n') || (rcvBuf
[i
] == '\r')) {
517 /* a labelled break would be nice here.... */
521 if (ortn
== errSSLWouldBlock
) {
528 doPause("Client GET msg received");
531 /* send out canned response */
532 length
= strlen(outMsg
);
533 ortn
= SSLWrite(ctx
, outMsg
, length
, &length
);
535 printSslErrStr("SSLWrite", ortn
);
538 doPause("Server response sent");
542 * always do close, even on error - to flush outgoing write queue
544 OSStatus cerr
= SSLClose(ctx
);
549 endpointShutdown(acceptSock
);
552 SSLDisposeContext(ctx
);
554 /* FIXME - dispose of serverCerts */
558 static void showPeerCerts(
559 CFArrayRef peerCerts
,
563 SecCertificateRef certRef
;
568 if(peerCerts
== NULL
) {
571 numCerts
= CFArrayGetCount(peerCerts
);
572 for(i
=0; i
<numCerts
; i
++) {
573 certRef
= (SecCertificateRef
)CFArrayGetValueAtIndex(peerCerts
, i
);
574 ortn
= SecCertificateGetData(certRef
, &certData
);
576 printf("***SecCertificateGetData returned %d\n", (int)ortn
);
579 printf("\n================== Peer Cert %lu ===================\n\n", i
);
580 printCert(certData
.Data
, certData
.Length
, verbose
);
581 printf("\n=============== End of Peer Cert %lu ===============\n", i
);
585 static void writePeerCerts(
586 CFArrayRef peerCerts
,
587 const char *fileBase
)
590 SecCertificateRef certRef
;
596 if(peerCerts
== NULL
) {
599 numCerts
= CFArrayGetCount(peerCerts
);
600 for(i
=0; i
<numCerts
; i
++) {
601 sprintf(fileName
, "%s%02d.cer", fileBase
, (int)i
);
602 certRef
= (SecCertificateRef
)CFArrayGetValueAtIndex(peerCerts
, i
);
603 ortn
= SecCertificateGetData(certRef
, &certData
);
605 printf("***SecCertificateGetData returned %d\n", (int)ortn
);
608 cspWriteFile(fileName
, certData
.Data
, certData
.Length
);
610 printf("...wrote %lu certs to fileBase %s\n", numCerts
, fileBase
);
613 static void showSSLResult(
614 SSLProtocol tryVersion
,
617 SSLProtocol negVersion
,
618 SSLCipherSuite negCipher
,
619 Boolean sessionWasResumed
,
620 unsigned char *sessionID
,
621 size_t sessionIDLength
,
622 CFArrayRef peerCerts
,
623 CSSM_BOOL displayPeerCerts
,
624 SSLClientCertificateState certState
,
625 char *fileBase
) // non-NULL: write certs to file
627 CFIndex numPeerCerts
;
631 printf(" Allowed SSL versions : %s\n", acceptedProts
);
634 printf(" Attempted SSL version : %s\n",
635 sslGetProtocolVersionString(tryVersion
));
637 printf(" Result : %s\n", sslGetSSLErrString(err
));
638 printf(" Negotiated SSL version : %s\n",
639 sslGetProtocolVersionString(negVersion
));
640 printf(" Negotiated CipherSuite : %s\n",
641 sslGetCipherSuiteString(negCipher
));
642 if(certState
!= kSSLClientCertNone
) {
643 printf(" Client Cert State : %s\n",
644 sslGetClientCertStateString(certState
));
646 printf(" Resumed Session : ");
647 if(sessionWasResumed
) {
648 for(unsigned dex
=0; dex
<sessionIDLength
; dex
++) {
649 printf("%02X ", sessionID
[dex
]);
650 if(((dex
% 8) == 7) && (dex
!= (sessionIDLength
- 1))) {
657 printf("NOT RESUMED\n");
659 if(peerCerts
== NULL
) {
663 numPeerCerts
= CFArrayGetCount(peerCerts
);
665 printf(" Number of peer certs : %lu\n", numPeerCerts
);
666 if(numPeerCerts
!= 0) {
667 if(displayPeerCerts
) {
668 showPeerCerts(peerCerts
, CSSM_FALSE
);
670 if(fileBase
!= NULL
) {
671 writePeerCerts(peerCerts
, fileBase
);
677 static int verifyClientCertState(
678 CSSM_BOOL verifyCertState
,
679 SSLClientCertificateState expectState
,
680 SSLClientCertificateState gotState
)
682 if(!verifyCertState
) {
685 if(expectState
== gotState
) {
688 printf("***Expected clientCertState %s; got %s\n",
689 sslGetClientCertStateString(expectState
),
690 sslGetClientCertStateString(gotState
));
694 int main(int argc
, char **argv
)
698 char fullFileBase
[100];
699 SSLProtocol negVersion
;
700 SSLCipherSuite negCipher
;
701 Boolean sessionWasResumed
;
702 unsigned char sessionID
[MAX_SESSION_ID_LENGTH
];
703 size_t sessionIDLength
;
704 CFArrayRef peerCerts
= NULL
;
707 CFArrayRef serverCerts
= nil
; // required
708 CFArrayRef encryptCerts
= nil
; // optional
709 SecKeychainRef serverKc
= nil
;
710 SecKeychainRef encryptKc
= nil
;
713 SSLClientCertificateState certState
; // obtained from sslServe
714 unsigned char *caCert
;
716 SecCertificateRef secCert
;
720 /* user-spec'd parameters */
721 unsigned short portNum
= DEFAULT_PORT
;
722 CSSM_BOOL allowExpired
= CSSM_FALSE
;
723 CSSM_BOOL allowAnyRoot
= CSSM_FALSE
;
724 char *fileBase
= NULL
;
725 CSSM_BOOL displayRxData
= CSSM_FALSE
;
726 CSSM_BOOL displayCerts
= CSSM_FALSE
;
727 char cipherRestrict
= '\0';
728 SSLProtocol attemptProt
= kTLSProtocol1
;
729 CSSM_BOOL protXOnly
= CSSM_FALSE
; // kSSLProtocol3Only,
731 char *acceptedProts
= NULL
; // "23t" ==> SSLSetProtocolVersionEnabled
732 CSSM_BOOL quiet
= CSSM_FALSE
;
733 CSSM_BOOL resumableEnable
= CSSM_TRUE
;
734 CSSM_BOOL pause
= CSSM_FALSE
;
735 char *keyChainName
= NULL
;
736 char *encryptKeyChainName
= NULL
;
738 SSLAuthenticate authenticate
= kNeverAuthenticate
;
739 CSSM_BOOL nonBlocking
= CSSM_FALSE
;
740 CSSM_BOOL allowExpiredRoot
= CSSM_FALSE
;
741 CSSM_BOOL disableCertVerify
= CSSM_FALSE
;
742 char *anchorFile
= NULL
;
743 CSSM_BOOL replaceAnchors
= CSSM_FALSE
;
744 CSSM_BOOL vfyCertState
= CSSM_FALSE
;
745 SSLClientCertificateState expectCertState
;
746 char *password
= NULL
;
747 char *dhParamsFile
= NULL
;
748 unsigned char *dhParams
= NULL
;
749 unsigned dhParamsLen
= 0;
750 CSSM_BOOL doIdSearch
= CSSM_FALSE
;
751 CSSM_BOOL completeCertChain
= CSSM_FALSE
;
752 uint32 sessionCacheTimeout
= 0;
753 CSSM_BOOL disableAnonCiphers
= CSSM_FALSE
;
754 CFMutableArrayRef acceptableDNList
= NULL
;
756 for(arg
=1; arg
<argc
; arg
++) {
760 portNum
= atoi(&argp
[2]);
763 keyChainName
= &argp
[2];
766 encryptKeyChainName
= &argp
[2];
769 allowExpired
= CSSM_TRUE
;
772 allowExpiredRoot
= CSSM_TRUE
;
775 disableCertVerify
= CSSM_TRUE
;
779 /* requires another arg */
782 anchorFile
= argv
[arg
];
786 /* requires another arg */
789 anchorFile
= argv
[arg
];
790 replaceAnchors
= CSSM_TRUE
;
796 vfyCertState
= CSSM_TRUE
;
799 expectCertState
= kSSLClientCertNone
;
802 expectCertState
= kSSLClientCertRequested
;
805 expectCertState
= kSSLClientCertSent
;
808 expectCertState
= kSSLClientCertRejected
;
815 allowAnyRoot
= CSSM_TRUE
;
818 displayRxData
= CSSM_TRUE
;
821 displayCerts
= CSSM_TRUE
;
827 cipherRestrict
= argp
[2];
830 attemptProt
= kSSLProtocol2
;
833 attemptProt
= kSSLProtocol3
;
836 attemptProt
= kTLSProtocol1
;
839 protXOnly
= CSSM_TRUE
;
845 acceptedProts
= &argp
[2];
848 resumableEnable
= CSSM_FALSE
;
851 nonBlocking
= CSSM_TRUE
;
858 case 'a': authenticate
= kAlwaysAuthenticate
; break;
859 case 'n': authenticate
= kNeverAuthenticate
; break;
860 case 't': authenticate
= kTryAuthenticate
; break;
861 default: usage(argv
);
866 /* requires another arg */
869 dhParamsFile
= argv
[arg
];
875 doIdSearch
= CSSM_TRUE
;
878 completeCertChain
= CSSM_TRUE
;
881 sessionCacheTimeout
= atoi(&argp
[2]);
884 disableAnonCiphers
= CSSM_TRUE
;
894 /* requires another arg */
897 if(cspReadFile(argv
[arg
], &caCert
, &caCertLen
)) {
898 printf("***Error reading file %s. Aborting.\n", argv
[arg
]);
901 if(acceptableDNList
== NULL
) {
902 acceptableDNList
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
904 certData
.Data
= caCert
;
905 certData
.Length
= caCertLen
;
906 ortn
= SecCertificateCreateFromData(&certData
,
908 CSSM_CERT_ENCODING_DER
,
911 cssmPerror("SecCertificateCreateFromData", ortn
);
914 CFArrayAppendValue(acceptableDNList
, secCert
);
919 if(argp
[1] == '\0') {
920 /* no loop count --> loop forever */
924 else if(argp
[1] != '=') {
927 loops
= atoi(&argp
[2]);
934 /* get server cert and optional encryption cert as CFArrayRef */
936 serverCerts
= getSslCerts(keyChainName
, CSSM_FALSE
, completeCertChain
,
937 anchorFile
, &serverKc
);
938 if(serverCerts
== nil
) {
942 else if(doIdSearch
) {
943 OSStatus ortn
= sslIdentityPicker(NULL
, anchorFile
, true, NULL
, &serverCerts
);
945 printf("***IdentitySearch failure; aborting.\n");
950 OSStatus ortn
= SecKeychainUnlock(serverKc
, strlen(password
), password
, true);
952 printf("SecKeychainUnlock returned %d\n", (int)ortn
);
956 if(encryptKeyChainName
) {
957 encryptCerts
= getSslCerts(encryptKeyChainName
, CSSM_TRUE
, completeCertChain
,
958 anchorFile
, &encryptKc
);
959 if(encryptCerts
== nil
) {
964 switch(attemptProt
) {
966 attemptProt
= kTLSProtocol1Only
;
969 attemptProt
= kSSLProtocol3Only
;
976 int r
= cspReadFile(dhParamsFile
, &dhParams
, &dhParamsLen
);
978 printf("***Error reading diffie-hellman params from %s; aborting\n",
983 /* one-time only server port setup */
984 err
= ListenForClients(portNum
, nonBlocking
, &listenSock
);
986 printf("ListenForClients returned %d; aborting\n", (int)err
);
990 for(loopNum
=1; ; loopNum
++) {
991 err
= sslServe(listenSock
,
1010 sessionCacheTimeout
,
1026 SSLProtocol tryProt
= attemptProt
;
1027 showSSLResult(tryProt
,
1038 fileBase
? fullFileBase
: NULL
);
1040 errCount
+= verifyClientCertState(vfyCertState
, expectCertState
,
1042 freePeerCerts(peerCerts
);
1043 if(loops
&& (loopNum
== loops
)) {
1048 endpointShutdown(listenSock
);
1049 printCertShutdown();
1051 CFRelease(serverKc
);
1054 CFRelease(encryptKc
);