2  * Copyright (c) 2008-2013 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  * Trivial SSL server example, using SecureTransport / OS X version. 
  27  * Written by Doug Mitchell.  
  29 #include <Security/SecureTransport.h> 
  30 #include <Security/SecureTransportPriv.h> 
  31 #include "sslAppUtils.h" 
  33 #include "utilities/fileIo.h" 
  35 #include <Security/SecBase.h> 
  42 #include <sys/param.h> 
  44 #include <Security/Security.h> 
  45 #include <Security/SecCertificatePriv.h> 
  47 #include <CoreFoundation/CoreFoundation.h> 
  48 #include "SecurityTool/sharedTool/print_cert.h" 
  51 #include <securityd/spi.h> 
  54 /* Set true when PR-3074739 is merged to TOT */ 
  55 #define SET_DH_PARAMS_ENABLE            1 
  57 /* true when using SSLCopyPeerCertificates() per Radar 3311892 */ 
  58 #define USE_COPY_PEER_CERTS             1 
  61  * Defaults, overridable by user.  
  63 #define SERVER_MESSAGE  "HTTP/1.0 200 OK\015\012Content-Type: text/html\015\012\015\012" \ 
  64         "<HTML><HEAD><TITLE>SecureTransport Test Server</TITLE></HEAD>" \ 
  65         "<BODY><H2>Secure connection established.</H2>" \ 
  66         "Message from the 'sslServer' sample application.\015\012</BODY>" \ 
  69 /* For ease of debugging, pick a non-privileged port */ 
  70 #define DEFAULT_PORT     1200 
  71 // #define DEFAULT_PORT     443 
  73 #define DEFAULT_HOST    "localhost" 
  75 #define DEFAULT_KC              "certkc" 
  77 static void usage(char **argv
) 
  79     printf("Usage: %s [option ...]\n", argv
[0]); 
  81         printf("   P=port      Port to listen on; default is %d\n", DEFAULT_PORT
); 
  82         printf("   k=keychain  Contains server cert and keys.\n"); 
  83         printf("   y=keychain  Encryption-only cert and keys.\n"); 
  84     printf("   e           Allow Expired Certs\n"); 
  85     printf("   r           Allow any root cert\n"); 
  86     printf("   E           Allow Expired Roots\n"); 
  87         printf("   x           Disable Cert Verification\n"); 
  88         printf("   f=fileBase  Write Peer Certs to fileBase*\n"); 
  89         printf("   c           Display peer certs\n"); 
  90         printf("   d           Display received data\n"); 
  91         printf("   C=cipherSuite (e=40-bit d=DES D=40-bit DES 3=3DES 4=RC4 $=40-bit RC4\n" 
  92                    "                  2=RC2 a=AES128 A=AES256 h=DH H=Anon DH r=DHE/RSA s=DH/DSS\n" 
  94         printf("   2           SSLv2 only (default is best fit)\n"); 
  95         printf("   3           SSLv3 only (default is best fit)\n"); 
  96         printf("   t           TLSv1 only (default is best fit)\n"); 
  97         printf("   o           TLSv1, SSLv3 use kSSLProtocol__X__Only\n"); 
  98         printf("   g={prot...} Specify legal protocols; prot = any combo of [23t]\n"); 
  99         printf("   T=[nrsj]    Verify client cert state = " 
 100                                                         "none/requested/sent/rejected\n"); 
 101         printf("   R           Disable resumable session support\n"); 
 102         printf("   i=timeout   Session cache timeout\n"); 
 103         printf("   u=[nat]     Authentication: n=never; a=always; t=try\n"); 
 104         printf("   b           Non-blocking I/O\n"); 
 105         printf("   a fileNmae  Add fileName to list of trusted roots\n"); 
 106         printf("   A fileName  fileName is ONLY trusted root\n"); 
 107         printf("   U filename  Add filename to acceptable DNList (multiple times OK)\n"); 
 108         printf("   D filename  Diffie-Hellman parameters from filename\n"); 
 109         printf("   z=password  Unlock server keychain with password.\n"); 
 110         printf("   H           Do SecIndentityRef search instead of specific keychain\n"); 
 111         printf("   M           Complete cert chain (default assumes that our identity is root)\n"); 
 112         printf("   4           Disable anonymous ciphers\n"); 
 113         printf("   p           Pause after each phase\n"); 
 114         printf("   l[=loops]   Loop, performing multiple transactions\n"); 
 115         printf("   q           Quiet/diagnostic mode (site names and errors only)\n"); 
 120 /* snag a copy of current connection's peer certs so we can  
 121  * examine them later after the connection is closed */ 
 122 static OSStatus 
copyPeerCerts( 
 124         CFArrayRef      
*peerCerts
)             // mallocd & RETURNED 
 126         #if USE_COPY_PEER_CERTS 
 127         OSStatus ortn 
= SSLCopyPeerCertificates(ctx
, peerCerts
); 
 129         OSStatus ortn 
= SSLGetPeerCertificates(ctx
, peerCerts
); 
 132                 printf("***Error obtaining peer certs: %s\n", 
 133                         sslGetSSLErrString(ortn
)); 
 138 /* free the cert array obtained via SSLGetPeerCertificates() */ 
 139 static void     freePeerCerts( 
 140         CFArrayRef                      peerCerts
) 
 142         if(peerCerts 
== NULL
) { 
 146         #if USE_COPY_PEER_CERTS 
 148         /* Voila! Problem fixed. */ 
 149         CFRelease(peerCerts
); 
 155         SecCertificateRef certData
; 
 158         numCerts 
= CFArrayGetCount(peerCerts
); 
 159         for(i
=0; i
<numCerts
; i
++) { 
 160                 certData 
= (SecCertificateRef
)CFArrayGetValueAtIndex(peerCerts
, i
); 
 163         CFRelease(peerCerts
); 
 167 /* print reply received from server */ 
 168 static void dumpAscii( 
 172         char *cp 
= (char *)rcvBuf
; 
 176         for(i
=0; i
<len
; i
++) { 
 189                                 if(isprint(c
) && (c 
!= '\n')) { 
 193                                         printf("<%02X>", ((unsigned)c
) & 0xff); 
 202 static void doPause(const char *prompt
) {        
 204                 printf("%s. ", prompt
); 
 207         printf("Continue (n/anything)? "); 
 215  * Perform one SSL diagnostic server-side session. Returns nonzero on error.  
 216  * Normally no output to stdout except initial "waiting for connection" message,  
 217  * unless there is a really screwed up error (i.e., something not directly related  
 218  * to the SSL connection).  
 220 #define RCV_BUF_SIZE            256 
 222 static OSStatus 
sslServe( 
 224         unsigned short                  portNum
, 
 225         SSLProtocol                             tryVersion
,                     // only used if acceptedProts NULL 
 226         const char                              *acceptedProts
, 
 227         CFArrayRef                              serverCerts
,            // required 
 228         char                                    *password
,                      // optional 
 231         bool                            allowExpiredRoot
, 
 232         bool                            disableCertVerify
, 
 235         char                                    cipherRestrict
,         // '2', 'd'. etc...'\0' for no 
 237         SSLAuthenticate                 authenticate
, 
 238         unsigned char                   *dhParams
,                      // optional D-H parameters       
 239         unsigned                                dhParamsLen
, 
 240         CFArrayRef                              acceptableDNList
,       // optional  
 241         bool                            resumableEnable
, 
 242         uint32_t                                        sessionCacheTimeout
,// optional 
 243         bool                            disableAnonCiphers
, 
 244         bool                            silent
,                         // no stdout 
 246         SSLProtocol                             
*negVersion
,            // RETURNED 
 247         SSLCipherSuite                  
*negCipher
,                     // RETURNED 
 248         SSLClientCertificateState 
*certState
,           // RETURNED 
 249         Boolean                                 
*sessionWasResumed
,     // RETURNED 
 250         unsigned char                   *sessionID
,                     // mallocd by caller, RETURNED 
 251         size_t                                  *sessionIDLength
,       // RETURNED 
 252         CFArrayRef                              
*peerCerts
,                     // mallocd & RETURNED 
 258     SSLContextRef       ctx 
= NULL
; 
 260     uint8_t             rcvBuf
[RCV_BUF_SIZE
]; 
 261         const char *outMsg 
= SERVER_MESSAGE
; 
 263 #pragma clang diagnostic push 
 264 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 
 265     *negVersion 
= kSSLProtocolUnknown
; 
 266     *negCipher 
= SSL_NULL_WITH_NULL_NULL
; 
 270         signal(SIGPIPE
, sigpipe
); 
 273         /* first wait for a connection */ 
 275                 printf("Waiting for client connection on port %u...", portNum
); 
 278         ortn 
= AcceptClientConnection(listenSock
, &acceptSock
, &peerId
); 
 280         printf("AcceptClientConnection returned %d; aborting\n", (int)ortn
); 
 285          * Set up a SecureTransport session. 
 286          * First the standard calls. 
 288         ortn 
= SSLNewContext(true, &ctx
); 
 290                 printSslErrStr("SSLNewContext", ortn
); 
 293         ortn 
= SSLSetIOFuncs(ctx
, SocketRead
, SocketWrite
); 
 295                 printSslErrStr("SSLSetIOFuncs", ortn
); 
 298         ortn 
= SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)acceptSock
); 
 300                 printSslErrStr("SSLSetConnection", ortn
); 
 304         /* have to do these options befor setting server certs */ 
 306                 ortn 
= SSLSetAllowsExpiredCerts(ctx
, true); 
 308                         printSslErrStr("SSLSetAllowExpiredCerts", ortn
); 
 313                 ortn 
= SSLSetAllowsAnyRoot(ctx
, true); 
 315                         printSslErrStr("SSLSetAllowAnyRoot", ortn
); 
 321                 ortn 
= sslAddTrustedRoot(ctx
, anchorFile
, replaceAnchors
); 
 323                         printf("***Error obtaining anchor file %s\n", anchorFile
); 
 327         if(serverCerts 
!= NULL
) { 
 328                 if(anchorFile 
== NULL
) { 
 329                         /* no specific anchors, so assume we want to trust this one */ 
 330                         ortn 
= addIdentityAsTrustedRoot(ctx
, serverCerts
); 
 335                 ortn 
= SSLSetCertificate(ctx
, serverCerts
); 
 337                         printSslErrStr("SSLSetCertificate", ortn
); 
 341         if(allowExpiredRoot
) { 
 342                 ortn 
= SSLSetAllowsExpiredRoots(ctx
, true); 
 344                         printSslErrStr("SSLSetAllowsExpiredRoots", ortn
); 
 348         if(disableCertVerify
) { 
 349                 ortn 
= SSLSetEnableCertVerify(ctx
, false); 
 351                         printSslErrStr("SSLSetEnableCertVerify", ortn
); 
 357          * SecureTransport options. 
 360                 ortn 
= SSLSetProtocolVersionEnabled(ctx
, kSSLProtocolAll
, false); 
 362                         printSslErrStr("SSLSetProtocolVersionEnabled(all off)", ortn
); 
 365                 for(const char *cp 
= acceptedProts
; *cp
; cp
++) { 
 366                         SSLProtocol prot 
= kSSLProtocolUnknown
; 
 369                                         prot 
= kSSLProtocol2
; 
 372                                         prot 
= kSSLProtocol3
; 
 375                                         prot 
= kTLSProtocol1
; 
 380                         ortn 
= SSLSetProtocolVersionEnabled(ctx
, prot
, true); 
 382                                 printSslErrStr("SSLSetProtocolVersionEnabled", ortn
); 
 388                 ortn 
= SSLSetProtocolVersion(ctx
, tryVersion
); 
 390                         printSslErrStr("SSLSetProtocolVersion", ortn
); 
 394         if(resumableEnable
) { 
 395                 ortn 
= SSLSetPeerID(ctx
, &peerId
, sizeof(PeerSpec
)); 
 397                         printSslErrStr("SSLSetPeerID", ortn
); 
 401         if(cipherRestrict 
!= '\0') { 
 402                 ortn 
= sslSetCipherRestrictions(ctx
, cipherRestrict
); 
 407         if(authenticate 
!= kNeverAuthenticate
) { 
 408                 ortn 
= SSLSetClientSideAuthenticate(ctx
, authenticate
); 
 410                         printSslErrStr("SSLSetClientSideAuthenticate", ortn
); 
 415                 ortn 
= SSLSetDiffieHellmanParams(ctx
, dhParams
, dhParamsLen
); 
 417                         printSslErrStr("SSLSetDiffieHellmanParams", ortn
); 
 421         if(sessionCacheTimeout
) { 
 422                 ortn 
= SSLSetSessionCacheTimeout(ctx
, sessionCacheTimeout
); 
 424                         printSslErrStr("SSLSetSessionCacheTimeout", ortn
); 
 428         if(disableAnonCiphers
) { 
 429                 ortn 
= SSLSetAllowAnonymousCiphers(ctx
, false); 
 431                         printSslErrStr("SSLSetAllowAnonymousCiphers", ortn
); 
 434                 /* quickie test of the getter */ 
 436                 ortn 
= SSLGetAllowAnonymousCiphers(ctx
, &e
); 
 438                         printSslErrStr("SSLGetAllowAnonymousCiphers", ortn
); 
 442                         printf("***SSLGetAllowAnonymousCiphers() returned true; expected false\n"); 
 448         if(acceptableDNList) { 
 449                 ortn = SSLSetCertificateAuthorities(ctx, acceptableDNList, TRUE); 
 451                         printSslErrStr("SSLSetCertificateAuthorities", ortn); 
 459                 doPause("SSLContext initialized"); 
 462         /* Perform SSL/TLS handshake */ 
 464     {   ortn 
= SSLHandshake(ctx
); 
 465             if((ortn 
== errSSLWouldBlock
) && !silent
) { 
 466                 /* keep UI responsive */  
 469     } while (ortn 
== errSSLWouldBlock
); 
 471         /* this works even if handshake failed due to cert chain invalid */ 
 472         copyPeerCerts(ctx
, peerCerts
); 
 474         SSLGetClientCertificateState(ctx
, certState
); 
 475         SSLGetNegotiatedCipher(ctx
, negCipher
); 
 476         SSLGetNegotiatedProtocolVersion(ctx
, negVersion
); 
 477         *sessionIDLength 
= MAX_SESSION_ID_LENGTH
; 
 478         ortn 
= SSLGetResumableSessionInfo(ctx
, sessionWasResumed
, sessionID
, sessionIDLength
); 
 487                 doPause("SSLContext handshake complete"); 
 490         /* wait for one complete line or user says they've had enough */ 
 491         while(ortn 
== errSecSuccess
) { 
 492             length 
= sizeof(rcvBuf
); 
 493             ortn 
= SSLRead(ctx
, rcvBuf
, length
, &length
); 
 495                 /* keep UI responsive */  
 499                 /* print what we have */ 
 500                 printf("client request: "); 
 501                 dumpAscii(rcvBuf
, length
); 
 504                 /* allow user to bail */ 
 508                 printf("\nMore client request (y/anything): "); 
 515             /* poor person's line completion scan */ 
 516             for(unsigned i
=0; i
<length
; i
++) { 
 517                 if((rcvBuf
[i
] == '\n') || (rcvBuf
[i
] == '\r')) { 
 518                         /* a labelled break would be nice here.... */ 
 522             if (ortn 
== errSSLWouldBlock
) { 
 523                 ortn 
= errSecSuccess
; 
 529                 doPause("Client GET msg received"); 
 532         /* send out canned response */ 
 533         length 
= strlen(outMsg
); 
 534         ortn 
= SSLWrite(ctx
, outMsg
, length
, &length
); 
 536                 printSslErrStr("SSLWrite", ortn
); 
 539                 doPause("Server response sent"); 
 543          * always do close, even on error - to flush outgoing write queue  
 545         OSStatus cerr 
= SSLClose(ctx
); 
 546         if(ortn 
== errSecSuccess
) { 
 550                 endpointShutdown(acceptSock
); 
 553             SSLDisposeContext(ctx
);   
 556 #pragma clang diagnostic pop 
 558         /* FIXME - dispose of serverCerts */ 
 562 static void showPeerCerts( 
 563         CFArrayRef                      peerCerts
, 
 567         SecCertificateRef certRef
; 
 570         if(peerCerts 
== NULL
) { 
 573         numCerts 
= CFArrayGetCount(peerCerts
); 
 574         for(i
=0; i
<numCerts
; i
++) { 
 575                 certRef 
= (SecCertificateRef
)CFArrayGetValueAtIndex(peerCerts
, i
); 
 576                 printf("\n================== Server Cert %lu ===================\n\n", i
); 
 577         print_cert(certRef
, verbose
); 
 578                 printf("\n=============== End of Server Cert %lu ===============\n", i
); 
 582 static void writePeerCerts( 
 583         CFArrayRef                      peerCerts
, 
 584         const char                      *fileBase
) 
 587         SecCertificateRef certRef
; 
 591         if(peerCerts 
== NULL
) { 
 594         numCerts 
= CFArrayGetCount(peerCerts
); 
 595         for(i
=0; i
<numCerts
; i
++) { 
 596                 sprintf(fileName
, "%s%02d.cer", fileBase
, (int)i
); 
 597                 certRef 
= (SecCertificateRef
)CFArrayGetValueAtIndex(peerCerts
, i
); 
 598                 writeFileSizet(fileName
, SecCertificateGetBytePtr(certRef
), 
 599                         SecCertificateGetLength(certRef
)); 
 601         printf("...wrote %lu certs to fileBase %s\n", numCerts
, fileBase
); 
 604 static void showSSLResult( 
 605         SSLProtocol                     tryVersion
, 
 608         SSLProtocol                     negVersion
, 
 609         SSLCipherSuite          negCipher
, 
 610         Boolean                         sessionWasResumed
,       
 611         unsigned char           *sessionID
,                      
 612         size_t                          sessionIDLength
,         
 613         CFArrayRef                      peerCerts
, 
 614         bool                    displayPeerCerts
, 
 615         SSLClientCertificateState       certState
, 
 616         char                            *fileBase
)              // non-NULL: write certs to file 
 618         CFIndex numPeerCerts
; 
 622                 printf("   Allowed SSL versions   : %s\n", acceptedProts
); 
 625                 printf("   Attempted  SSL version : %s\n",  
 626                         sslGetProtocolVersionString(tryVersion
)); 
 628         printf("   Result                 : %s\n", sslGetSSLErrString(err
)); 
 629         printf("   Negotiated SSL version : %s\n",  
 630                 sslGetProtocolVersionString(negVersion
)); 
 631         printf("   Negotiated CipherSuite : %s\n", 
 632                 sslGetCipherSuiteString(negCipher
)); 
 634 #pragma clang diagnostic push 
 635 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 
 636         if(certState 
!= kSSLClientCertNone
) { 
 637                 printf("   Client Cert State      : %s\n", 
 638                         sslGetClientCertStateString(certState
)); 
 640 #pragma clang diagnostic pop 
 642         printf("   Resumed Session        : "); 
 643         if(sessionWasResumed
) { 
 644                 for(unsigned dex
=0; dex
<sessionIDLength
; dex
++) { 
 645                         printf("%02X ", sessionID
[dex
]); 
 646                         if(((dex 
% 8) == 7) && (dex 
!= (sessionIDLength 
- 1))) { 
 653                 printf("NOT RESUMED\n"); 
 655         if(peerCerts 
== NULL
) { 
 659                 numPeerCerts 
= CFArrayGetCount(peerCerts
); 
 661         printf("   Number of peer certs : %lu\n", numPeerCerts
); 
 662         if(numPeerCerts 
!= 0) { 
 663                 if(displayPeerCerts
) { 
 664                         showPeerCerts(peerCerts
, false); 
 666                 if(fileBase 
!= NULL
) { 
 667                         writePeerCerts(peerCerts
, fileBase
); 
 673 static int verifyClientCertState( 
 674         bool                                    verifyCertState
, 
 675         SSLClientCertificateState       expectState
, 
 676         SSLClientCertificateState       gotState
) 
 678         if(!verifyCertState
) { 
 681         if(expectState 
== gotState
) { 
 684         printf("***Expected clientCertState %s; got %s\n", 
 685                 sslGetClientCertStateString(expectState
), 
 686                 sslGetClientCertStateString(gotState
)); 
 690 int main(int argc
, char **argv
) 
 694         char                            fullFileBase
[100]; 
 695         SSLProtocol                     negVersion
; 
 696         SSLCipherSuite          negCipher
; 
 697         Boolean                         sessionWasResumed
; 
 698         unsigned char           sessionID
[MAX_SESSION_ID_LENGTH
]; 
 699         size_t                          sessionIDLength
; 
 700         CFArrayRef                      peerCerts 
= NULL
;                
 703         CFArrayRef                      serverCerts 
= nil
;              // required 
 704         SecKeychainRef          serverKc 
= nil
; 
 707         SSLClientCertificateState certState
;            // obtained from sslServe 
 709 #pragma clang diagnostic push 
 710 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 
 712         /* user-spec'd parameters */ 
 713         unsigned short          portNum 
= DEFAULT_PORT
; 
 714         bool                    allowExpired 
= false; 
 715         bool                    allowAnyRoot 
= false; 
 716         char                            *fileBase 
= NULL
; 
 717         bool                    displayCerts 
= false; 
 718         char                            cipherRestrict 
= '\0'; 
 719         SSLProtocol                     attemptProt 
= kTLSProtocol1
; 
 720         bool                    protXOnly 
= false;      // kSSLProtocol3Only,  
 722         char                            *acceptedProts 
= NULL
;  // "23t" ==> SSLSetProtocolVersionEnabled 
 724         bool                    resumableEnable 
= true; 
 726         char                            *keyChainName 
= NULL
; 
 728         SSLAuthenticate         authenticate 
= kNeverAuthenticate
; 
 729         bool                    nonBlocking 
= false; 
 730         bool                    allowExpiredRoot 
= false; 
 731         bool                    disableCertVerify 
= false; 
 732         char                            *anchorFile 
= NULL
; 
 733         bool                    replaceAnchors 
= false; 
 734         bool                    vfyCertState 
= false; 
 735         SSLClientCertificateState expectCertState 
= kSSLClientCertNone
; 
 736         char                            *password 
= NULL
; 
 737         unsigned char           *dhParams 
= NULL
; 
 738         unsigned                        dhParamsLen 
= 0; 
 739         bool                    completeCertChain 
= false; 
 740         uint32_t                                sessionCacheTimeout 
= 0; 
 741         bool                    disableAnonCiphers 
= false; 
 742         CFMutableArrayRef       acceptableDNList 
= NULL
; 
 744         for(arg
=1; arg
<argc
; arg
++) { 
 748                                 portNum 
= atoi(&argp
[2]); 
 751                                 keyChainName 
= &argp
[2]; 
 757                                 allowExpiredRoot 
= true; 
 760                                 disableCertVerify 
= true; 
 764                                         /* requires another arg */ 
 767                                 anchorFile 
= argv
[arg
]; 
 771                                         /* requires another arg */ 
 774                                 anchorFile 
= argv
[arg
]; 
 775                                 replaceAnchors 
= true; 
 784                                                 expectCertState 
= kSSLClientCertNone
; 
 787                                                 expectCertState 
= kSSLClientCertRequested
; 
 790                                                 expectCertState 
= kSSLClientCertSent
; 
 793                                                 expectCertState 
= kSSLClientCertRejected
; 
 811                                 cipherRestrict 
= argp
[2]; 
 814                                 attemptProt 
= kSSLProtocol2
; 
 817                                 attemptProt 
= kSSLProtocol3
; 
 820                                 attemptProt 
= kTLSProtocol1
; 
 829                                 acceptedProts 
= &argp
[2]; 
 832                                 resumableEnable 
= false; 
 842                                         case 'a': authenticate 
= kAlwaysAuthenticate
; break; 
 843                                         case 'n': authenticate 
= kNeverAuthenticate
; break; 
 844                                         case 't': authenticate 
= kTryAuthenticate
; break; 
 845                                         default: usage(argv
); 
 850                                         /* requires another arg */ 
 860                                 completeCertChain 
= true; 
 863                                 sessionCacheTimeout 
= atoi(&argp
[2]); 
 866                                 disableAnonCiphers 
= true; 
 875                                 if(argp
[1] == '\0') { 
 876                                         /* no loop count --> loop forever */ 
 880                                 else if(argp
[1] != '=') { 
 883                                 loops 
= atoi(&argp
[2]); 
 892     securityd_init(NULL
); 
 896         /* get server cert and optional encryption cert as CFArrayRef */ 
 898                 serverCerts 
= getSslCerts(keyChainName
, false, completeCertChain
,  
 899                         anchorFile
, &serverKc
); 
 900                 if(serverCerts 
== nil
) { 
 903         } else if(protXOnly
) { 
 904                 switch(attemptProt
) { 
 906                                 attemptProt 
= kTLSProtocol1Only
; 
 909                                 attemptProt 
= kSSLProtocol3Only
; 
 916 #pragma clang diagnostic pop 
 918         /* one-time only server port setup */ 
 919         err 
= ListenForClients(portNum
, nonBlocking
, &listenSock
); 
 921         printf("ListenForClients returned %d; aborting\n", (int)err
); 
 925         for(loopNum
=1; ; loopNum
++) { 
 926                 err 
= sslServe(listenSock
, 
 960                         SSLProtocol tryProt 
= attemptProt
; 
 961                         showSSLResult(tryProt
, 
 972                                 fileBase 
? fullFileBase 
: NULL
); 
 974                 errCount 
+= verifyClientCertState(vfyCertState
, expectCertState
,  
 976                 freePeerCerts(peerCerts
); 
 977                 if(loops 
&& (loopNum 
== loops
)) { 
 982         endpointShutdown(listenSock
);