2  * Copyright (c) 2008-2014 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. 
  29 #include <Security/SecureTransport.h> 
  30 #include <Security/SecureTransportPriv.h> 
  31 #include "sslAppUtils.h" 
  35 #include <Security/SecBase.h> 
  41 #include <sys/param.h> 
  43 #include <Security/Security.h> 
  44 #include <Security/SecCertificatePriv.h> 
  46 #include <CoreFoundation/CoreFoundation.h> 
  47 #include "printCert.h" 
  50 #include <securityd/spi.h> 
  53 /* Set true when PR-3074739 is merged to TOT */ 
  54 #define SET_DH_PARAMS_ENABLE            1 
  56 /* true when using SSLCopyPeerCertificates() per Radar 3311892 */ 
  57 #define USE_COPY_PEER_CERTS             1 
  60  * Defaults, overridable by user. 
  62 #define SERVER_MESSAGE  "HTTP/1.0 200 OK\015\012Content-Type: text/html\015\012\015\012" \ 
  63         "<HTML><HEAD><TITLE>SecureTransport Test Server</TITLE></HEAD>" \ 
  64         "<BODY><H2>Secure connection established.</H2>" \ 
  65         "Message from the 'sslServer' sample application.\015\012</BODY>" \ 
  68 /* For ease of debugging, pick a non-privileged port */ 
  69 #define DEFAULT_PORT     1200 
  70 // #define DEFAULT_PORT     443 
  72 #define DEFAULT_HOST    "localhost" 
  74 #define DEFAULT_KC              "certkc" 
  76 static void usage(char **argv
) 
  78     printf("Usage: %s [option ...]\n", argv
[0]); 
  80         printf("   P=port      Port to listen on; default is %d\n", DEFAULT_PORT
); 
  81         printf("   k=keychain  Contains server cert and keys.\n"); 
  82         printf("   y=keychain  Encryption-only cert and keys.\n"); 
  83     printf("   e           Allow Expired Certs\n"); 
  84     printf("   r           Allow any root cert\n"); 
  85     printf("   E           Allow Expired Roots\n"); 
  86         printf("   x           Disable Cert Verification\n"); 
  87         printf("   f=fileBase  Write Peer Certs to fileBase*\n"); 
  88         printf("   c           Display peer certs\n"); 
  89         printf("   d           Display received data\n"); 
  90         printf("   C=cipherSuite (e=40-bit d=DES D=40-bit DES 3=3DES 4=RC4 $=40-bit RC4\n" 
  91                    "                  2=RC2 a=AES128 A=AES256 h=DH H=Anon DH r=DHE/RSA s=DH/DSS\n" 
  93         printf("   2           SSLv2 only (default is best fit)\n"); 
  94         printf("   3           SSLv3 only (default is best fit)\n"); 
  95         printf("   t           TLSv1 only (default is best fit)\n"); 
  96         printf("   o           TLSv1, SSLv3 use kSSLProtocol__X__Only\n"); 
  97         printf("   g={prot...} Specify legal protocols; prot = any combo of [23t]\n"); 
  98         printf("   T=[nrsj]    Verify client cert state = " 
  99                                                         "none/requested/sent/rejected\n"); 
 100         printf("   R           Disable resumable session support\n"); 
 101         printf("   i=timeout   Session cache timeout\n"); 
 102         printf("   u=[nat]     Authentication: n=never; a=always; t=try\n"); 
 103         printf("   b           Non-blocking I/O\n"); 
 104         printf("   a fileNmae  Add fileName to list of trusted roots\n"); 
 105         printf("   A fileName  fileName is ONLY trusted root\n"); 
 106         printf("   U filename  Add filename to acceptable DNList (multiple times OK)\n"); 
 107         printf("   D filename  Diffie-Hellman parameters from filename\n"); 
 108         printf("   z=password  Unlock server keychain with password.\n"); 
 109         printf("   H           Do SecIdentityRef search instead of specific keychain\n"); 
 110         printf("   M           Complete cert chain (default assumes that our identity is root)\n"); 
 111         printf("   4           Disable anonymous ciphers\n"); 
 112         printf("   p           Pause after each phase\n"); 
 113         printf("   l[=loops]   Loop, performing multiple transactions\n"); 
 114         printf("   q           Quiet/diagnostic mode (site names and errors only)\n"); 
 119 /* snag a copy of current connection's peer certs so we can 
 120  * examine them later after the connection is closed */ 
 121 static OSStatus 
copyPeerCerts( 
 123         CFArrayRef      
*peerCerts
)             // mallocd & RETURNED 
 125         #if USE_COPY_PEER_CERTS 
 126         OSStatus ortn 
= SSLCopyPeerCertificates(ctx
, peerCerts
); 
 128         OSStatus ortn 
= SSLGetPeerCertificates(ctx
, peerCerts
); 
 131                 printf("***Error obtaining peer certs: %s\n", 
 132                         sslGetSSLErrString(ortn
)); 
 137 /* free the cert array obtained via SSLGetPeerCertificates() */ 
 138 static void     freePeerCerts( 
 139         CFArrayRef                      peerCerts
) 
 141         if(peerCerts 
== NULL
) { 
 145         #if USE_COPY_PEER_CERTS 
 147         /* Voila! Problem fixed. */ 
 148         CFRelease(peerCerts
); 
 154         SecCertificateRef certData
; 
 157         numCerts 
= CFArrayGetCount(peerCerts
); 
 158         for(i
=0; i
<numCerts
; i
++) { 
 159                 certData 
= (SecCertificateRef
)CFArrayGetValueAtIndex(peerCerts
, i
); 
 162         CFRelease(peerCerts
); 
 166 /* print reply received from server */ 
 167 static void dumpAscii( 
 171         char *cp 
= (char *)rcvBuf
; 
 175         for(i
=0; i
<len
; i
++) { 
 188                                 if(isprint(c
) && (c 
!= '\n')) { 
 192                                         printf("<%02X>", ((unsigned)c
) & 0xff); 
 201 static void doPause(const char *prompt
) { 
 203                 printf("%s. ", prompt
); 
 206         printf("Continue (n/anything)? "); 
 214  * Perform one SSL diagnostic server-side session. Returns nonzero on error. 
 215  * Normally no output to stdout except initial "waiting for connection" message, 
 216  * unless there is a really screwed up error (i.e., something not directly related 
 217  * to the SSL connection). 
 219 #define RCV_BUF_SIZE            256 
 221 static OSStatus 
sslServe( 
 223         unsigned short                  portNum
, 
 224         SSLProtocol                             tryVersion
,                     // only used if acceptedProts NULL 
 225         const char                              *acceptedProts
, 
 226         CFArrayRef                              serverCerts
,            // required 
 227         char                                    *password
,                      // optional 
 228         CFArrayRef                              encryptServerCerts
,     // 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     *negVersion 
= kSSLProtocolUnknown
; 
 264     *negCipher 
= SSL_NULL_WITH_NULL_NULL
; 
 268         signal(SIGPIPE
, sigpipe
); 
 271         /* first wait for a connection */ 
 273                 printf("Waiting for client connection on port %u...", portNum
); 
 276         ortn 
= AcceptClientConnection(listenSock
, &acceptSock
, &peerId
); 
 278         printf("AcceptClientConnection returned %d; aborting\n", (int)ortn
); 
 283          * Set up a SecureTransport session. 
 284          * First the standard calls. 
 286         ortn 
= SSLNewContext(true, &ctx
); 
 288                 printSslErrStr("SSLNewContext", ortn
); 
 291         ortn 
= SSLSetIOFuncs(ctx
, SocketRead
, SocketWrite
); 
 293                 printSslErrStr("SSLSetIOFuncs", ortn
); 
 296         ortn 
= SSLSetConnection(ctx
, (SSLConnectionRef
)acceptSock
); 
 298                 printSslErrStr("SSLSetConnection", ortn
); 
 302         /* have to do these options befor setting server certs */ 
 304                 ortn 
= SSLSetAllowsExpiredCerts(ctx
, true); 
 306                         printSslErrStr("SSLSetAllowExpiredCerts", ortn
); 
 311                 ortn 
= SSLSetAllowsAnyRoot(ctx
, true); 
 313                         printSslErrStr("SSLSetAllowAnyRoot", ortn
); 
 319                 ortn 
= sslAddTrustedRoot(ctx
, anchorFile
, replaceAnchors
); 
 321                         printf("***Error obtaining anchor file %s\n", anchorFile
); 
 325         if(serverCerts 
!= NULL
) { 
 326                 if(anchorFile 
== NULL
) { 
 327                         /* no specific anchors, so assume we want to trust this one */ 
 328                         ortn 
= addIdentityAsTrustedRoot(ctx
, serverCerts
); 
 333                 ortn 
= SSLSetCertificate(ctx
, serverCerts
); 
 335                         printSslErrStr("SSLSetCertificate", ortn
); 
 339         if(encryptServerCerts
) { 
 340                 ortn 
= SSLSetEncryptionCertificate(ctx
, encryptServerCerts
); 
 342                         printSslErrStr("SSLSetEncryptionCertificate", ortn
); 
 346         if(allowExpiredRoot
) { 
 347                 ortn 
= SSLSetAllowsExpiredRoots(ctx
, true); 
 349                         printSslErrStr("SSLSetAllowsExpiredRoots", ortn
); 
 353         if(disableCertVerify
) { 
 354                 ortn 
= SSLSetEnableCertVerify(ctx
, false); 
 356                         printSslErrStr("SSLSetEnableCertVerify", ortn
); 
 362          * SecureTransport options. 
 365                 ortn 
= SSLSetProtocolVersionEnabled(ctx
, kSSLProtocolAll
, false); 
 367                         printSslErrStr("SSLSetProtocolVersionEnabled(all off)", ortn
); 
 370                 for(const char *cp 
= acceptedProts
; *cp
; cp
++) { 
 371                         SSLProtocol prot 
= kSSLProtocolUnknown
; 
 374                                         prot 
= kSSLProtocol2
; 
 377                                         prot 
= kSSLProtocol3
; 
 380                                         prot 
= kTLSProtocol1
; 
 385                         ortn 
= SSLSetProtocolVersionEnabled(ctx
, prot
, true); 
 387                                 printSslErrStr("SSLSetProtocolVersionEnabled", ortn
); 
 393                 ortn 
= SSLSetProtocolVersion(ctx
, tryVersion
); 
 395                         printSslErrStr("SSLSetProtocolVersion", ortn
); 
 399         if(resumableEnable
) { 
 400                 ortn 
= SSLSetPeerID(ctx
, &peerId
, sizeof(PeerSpec
)); 
 402                         printSslErrStr("SSLSetPeerID", ortn
); 
 406         if(cipherRestrict 
!= '\0') { 
 407                 ortn 
= sslSetCipherRestrictions(ctx
, cipherRestrict
); 
 412         if(authenticate 
!= kNeverAuthenticate
) { 
 413                 ortn 
= SSLSetClientSideAuthenticate(ctx
, authenticate
); 
 415                         printSslErrStr("SSLSetClientSideAuthenticate", ortn
); 
 420                 ortn 
= SSLSetDiffieHellmanParams(ctx
, dhParams
, dhParamsLen
); 
 422                         printSslErrStr("SSLSetDiffieHellmanParams", ortn
); 
 426         if(sessionCacheTimeout
) { 
 427                 ortn 
= SSLSetSessionCacheTimeout(ctx
, sessionCacheTimeout
); 
 429                         printSslErrStr("SSLSetSessionCacheTimeout", ortn
); 
 433         if(disableAnonCiphers
) { 
 434                 ortn 
= SSLSetAllowAnonymousCiphers(ctx
, false); 
 436                         printSslErrStr("SSLSetAllowAnonymousCiphers", ortn
); 
 439                 /* quickie test of the getter */ 
 441                 ortn 
= SSLGetAllowAnonymousCiphers(ctx
, &e
); 
 443                         printSslErrStr("SSLGetAllowAnonymousCiphers", ortn
); 
 447                         printf("***SSLGetAllowAnonymousCiphers() returned true; expected false\n"); 
 453         if(acceptableDNList) { 
 454                 ortn = SSLSetCertificateAuthorities(ctx, acceptableDNList, TRUE); 
 456                         printSslErrStr("SSLSetCertificateAuthorities", ortn); 
 464                 doPause("SSLContext initialized"); 
 467         /* Perform SSL/TLS handshake */ 
 469     {   ortn 
= SSLHandshake(ctx
); 
 470                 if((ortn 
== errSSLWouldBlock
) && !silent
) { 
 471                         /* keep UI responsive */ 
 474     } while (ortn 
== errSSLWouldBlock
); 
 476         /* this works even if handshake failed due to cert chain invalid */ 
 477         copyPeerCerts(ctx
, peerCerts
); 
 479         SSLGetClientCertificateState(ctx
, certState
); 
 480         SSLGetNegotiatedCipher(ctx
, negCipher
); 
 481         SSLGetNegotiatedProtocolVersion(ctx
, negVersion
); 
 482         *sessionIDLength 
= MAX_SESSION_ID_LENGTH
; 
 483         SSLGetResumableSessionInfo(ctx
, sessionWasResumed
, sessionID
, 
 493                 doPause("SSLContext handshake complete"); 
 496         /* wait for one complete line or user says they've had enough */ 
 497         while(ortn 
== errSecSuccess
) { 
 498                 length 
= sizeof(rcvBuf
); 
 499                 ortn 
= SSLRead(ctx
, rcvBuf
, length
, &length
); 
 501                         /* keep UI responsive */ 
 505                         /* print what we have */ 
 506                         printf("client request: "); 
 507                         dumpAscii(rcvBuf
, length
); 
 510                         /* allow user to bail */ 
 514                         printf("\nMore client request (y/anything): "); 
 521                 /* poor person's line completion scan */ 
 522                 for(unsigned i
=0; i
<length
; i
++) { 
 523                         if((rcvBuf
[i
] == '\n') || (rcvBuf
[i
] == '\r')) { 
 524                                 /* a labelled break would be nice here.... */ 
 528                 if (ortn 
== errSSLWouldBlock
) { 
 529                         ortn 
= errSecSuccess
; 
 535                 doPause("Client GET msg received"); 
 538         /* send out canned response */ 
 539         length 
= strlen(outMsg
); 
 540         ortn 
= SSLWrite(ctx
, outMsg
, length
, &length
); 
 542                 printSslErrStr("SSLWrite", ortn
); 
 545                 doPause("Server response sent"); 
 549          * always do close, even on error - to flush outgoing write queue 
 551         OSStatus cerr 
= SSLClose(ctx
); 
 552         if(ortn 
== errSecSuccess
) { 
 556                 endpointShutdown(acceptSock
); 
 559             SSLDisposeContext(ctx
); 
 561         /* FIXME - dispose of serverCerts */ 
 565 static void showPeerCerts( 
 566         CFArrayRef                      peerCerts
, 
 570         SecCertificateRef certRef
; 
 573         if(peerCerts 
== NULL
) { 
 576         numCerts 
= CFArrayGetCount(peerCerts
); 
 577         for(i
=0; i
<numCerts
; i
++) { 
 578                 certRef 
= (SecCertificateRef
)CFArrayGetValueAtIndex(peerCerts
, i
); 
 579                 printf("\n================== Server Cert %lu ===================\n\n", i
); 
 580                 print_cert(certRef
, verbose
); 
 581                 printf("\n=============== End of Server Cert %lu ===============\n", i
); 
 585 static void writePeerCerts( 
 586         CFArrayRef                      peerCerts
, 
 587         const char                      *fileBase
) 
 590         SecCertificateRef certRef
; 
 594         if(peerCerts 
== NULL
) { 
 597         numCerts 
= CFArrayGetCount(peerCerts
); 
 598         for(i
=0; i
<numCerts
; i
++) { 
 599                 sprintf(fileName
, "%s%02d.cer", fileBase
, (int)i
); 
 600                 certRef 
= (SecCertificateRef
)CFArrayGetValueAtIndex(peerCerts
, i
); 
 601                 writeFile(fileName
, SecCertificateGetBytePtr(certRef
), 
 602                         SecCertificateGetLength(certRef
)); 
 604         printf("...wrote %lu certs to fileBase %s\n", numCerts
, fileBase
); 
 607 static void showSSLResult( 
 608         SSLProtocol                     tryVersion
, 
 611         SSLProtocol                     negVersion
, 
 612         SSLCipherSuite          negCipher
, 
 613         Boolean                         sessionWasResumed
, 
 614         unsigned char           *sessionID
, 
 615         size_t                          sessionIDLength
, 
 616         CFArrayRef                      peerCerts
, 
 617         bool                    displayPeerCerts
, 
 618         SSLClientCertificateState       certState
, 
 619         char                            *fileBase
)              // non-NULL: write certs to file 
 621         CFIndex numPeerCerts
; 
 625                 printf("   Allowed SSL versions   : %s\n", acceptedProts
); 
 628                 printf("   Attempted  SSL version : %s\n", 
 629                         sslGetProtocolVersionString(tryVersion
)); 
 631         printf("   Result                 : %s\n", sslGetSSLErrString(err
)); 
 632         printf("   Negotiated SSL version : %s\n", 
 633                 sslGetProtocolVersionString(negVersion
)); 
 634         printf("   Negotiated CipherSuite : %s\n", 
 635                 sslGetCipherSuiteString(negCipher
)); 
 636         if(certState 
!= kSSLClientCertNone
) { 
 637                 printf("   Client Cert State      : %s\n", 
 638                         sslGetClientCertStateString(certState
)); 
 640         printf("   Resumed Session        : "); 
 641         if(sessionWasResumed
) { 
 642                 for(unsigned dex
=0; dex
<sessionIDLength
; dex
++) { 
 643                         printf("%02X ", sessionID
[dex
]); 
 644                         if(((dex 
% 8) == 7) && (dex 
!= (sessionIDLength 
- 1))) { 
 651                 printf("NOT RESUMED\n"); 
 653         if(peerCerts 
== NULL
) { 
 657                 numPeerCerts 
= CFArrayGetCount(peerCerts
); 
 659         printf("   Number of peer certs : %lu\n", numPeerCerts
); 
 660         if(numPeerCerts 
!= 0) { 
 661                 if(displayPeerCerts
) { 
 662                         showPeerCerts(peerCerts
, false); 
 664                 if(fileBase 
!= NULL
) { 
 665                         writePeerCerts(peerCerts
, fileBase
); 
 671 static int verifyClientCertState( 
 672         bool                                    verifyCertState
, 
 673         SSLClientCertificateState       expectState
, 
 674         SSLClientCertificateState       gotState
) 
 676         if(!verifyCertState
) { 
 679         if(expectState 
== gotState
) { 
 682         printf("***Expected clientCertState %s; got %s\n", 
 683                 sslGetClientCertStateString(expectState
), 
 684                 sslGetClientCertStateString(gotState
)); 
 688 int main(int argc
, char **argv
) 
 692         char                            fullFileBase
[100]; 
 693         SSLProtocol                     negVersion
; 
 694         SSLCipherSuite          negCipher
; 
 695         Boolean                         sessionWasResumed
; 
 696         unsigned char           sessionID
[MAX_SESSION_ID_LENGTH
]; 
 697         size_t                          sessionIDLength
; 
 698         CFArrayRef                      peerCerts 
= NULL
; 
 701         CFArrayRef                      serverCerts 
= nil
;              // required 
 702         CFArrayRef                      encryptCerts 
= nil
;             // optional 
 703         SecKeychainRef          serverKc 
= nil
; 
 704         SecKeychainRef          encryptKc 
= nil
; 
 707         SSLClientCertificateState certState
;            // obtained from sslServe 
 709         /* user-spec'd parameters */ 
 710         unsigned short          portNum 
= DEFAULT_PORT
; 
 711         bool                    allowExpired 
= false; 
 712         bool                    allowAnyRoot 
= false; 
 713         char                            *fileBase 
= NULL
; 
 714         bool                    displayRxData 
= false; 
 715         bool                    displayCerts 
= false; 
 716         char                            cipherRestrict 
= '\0'; 
 717         SSLProtocol                     attemptProt 
= kTLSProtocol1
; 
 718         bool                    protXOnly 
= false;      // kSSLProtocol3Only, 
 720         char                            *acceptedProts 
= NULL
;  // "23t" ==> SSLSetProtocolVersionEnabled 
 722         bool                    resumableEnable 
= true; 
 724         char                            *keyChainName 
= NULL
; 
 725         char                            *encryptKeyChainName 
= NULL
; 
 727         SSLAuthenticate         authenticate 
= kNeverAuthenticate
; 
 728         bool                    nonBlocking 
= false; 
 729         bool                    allowExpiredRoot 
= false; 
 730         bool                    disableCertVerify 
= false; 
 731         char                            *anchorFile 
= NULL
; 
 732         bool                    replaceAnchors 
= false; 
 733         bool                    vfyCertState 
= false; 
 734         SSLClientCertificateState expectCertState 
= kSSLClientCertNone
; 
 735         char                            *password 
= NULL
; 
 736         char                            *dhParamsFile 
= NULL
; 
 737         unsigned char           *dhParams 
= NULL
; 
 738         unsigned                        dhParamsLen 
= 0; 
 739         bool                    doIdSearch 
= false; 
 740         bool                    completeCertChain 
= false; 
 741         uint32_t                                sessionCacheTimeout 
= 0; 
 742         bool                    disableAnonCiphers 
= false; 
 743         CFMutableArrayRef       acceptableDNList 
= NULL
; 
 745         for(arg
=1; arg
<argc
; arg
++) { 
 749                                 portNum 
= atoi(&argp
[2]); 
 752                                 keyChainName 
= &argp
[2]; 
 755                                 encryptKeyChainName 
= &argp
[2]; 
 761                                 allowExpiredRoot 
= true; 
 764                                 disableCertVerify 
= true; 
 768                                         /* requires another arg */ 
 771                                 anchorFile 
= argv
[arg
]; 
 775                                         /* requires another arg */ 
 778                                 anchorFile 
= argv
[arg
]; 
 779                                 replaceAnchors 
= true; 
 788                                                 expectCertState 
= kSSLClientCertNone
; 
 791                                                 expectCertState 
= kSSLClientCertRequested
; 
 794                                                 expectCertState 
= kSSLClientCertSent
; 
 797                                                 expectCertState 
= kSSLClientCertRejected
; 
 807                                 displayRxData 
= true; 
 816                                 cipherRestrict 
= argp
[2]; 
 819                                 attemptProt 
= kSSLProtocol2
; 
 822                                 attemptProt 
= kSSLProtocol3
; 
 825                                 attemptProt 
= kTLSProtocol1
; 
 834                                 acceptedProts 
= &argp
[2]; 
 837                                 resumableEnable 
= false; 
 847                                         case 'a': authenticate 
= kAlwaysAuthenticate
; break; 
 848                                         case 'n': authenticate 
= kNeverAuthenticate
; break; 
 849                                         case 't': authenticate 
= kTryAuthenticate
; break; 
 850                                         default: usage(argv
); 
 855                                         /* requires another arg */ 
 858                                 dhParamsFile 
= argv
[arg
]; 
 867                                 completeCertChain 
= true; 
 870                                 sessionCacheTimeout 
= atoi(&argp
[2]); 
 873                                 disableAnonCiphers 
= true; 
 884                                         /* requires another arg */ 
 887                                 if(cspReadFile(argv
[arg
], &caCert
, &caCertLen
)) { 
 888                                         printf("***Error reading file %s. Aborting.\n", argv
[arg
]); 
 891                                 if(acceptableDNList 
== NULL
) { 
 892                                         acceptableDNList 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 894                                 certData
.Data 
= caCert
; 
 895                                 certData
.Length 
= caCertLen
; 
 896                                 ortn 
= SecCertificateCreateFromData(&certData
, 
 898                                                                                                         CSSM_CERT_ENCODING_DER
, 
 901                                         cssmPerror("SecCertificateCreateFromData", ortn
); 
 904                                 CFArrayAppendValue(acceptableDNList
, secCert
); 
 909                                 if(argp
[1] == '\0') { 
 910                                         /* no loop count --> loop forever */ 
 914                                 else if(argp
[1] != '=') { 
 917                                 loops 
= atoi(&argp
[2]); 
 930         /* get server cert and optional encryption cert as CFArrayRef */ 
 932                 serverCerts 
= getSslCerts(keyChainName
, false, completeCertChain
, 
 933                         anchorFile
, &serverKc
); 
 934                 if(serverCerts 
== nil
) { 
 941                 OSStatus ortn 
= sslIdentityPicker(NULL
, anchorFile
, true, NULL
, &serverCerts
); 
 943                         printf("***IdentitySearch failure; aborting.\n"); 
 948                 OSStatus ortn 
= SecKeychainUnlock(serverKc
, strlen(password
), password
, true); 
 950                         printf("SecKeychainUnlock returned %d\n", (int)ortn
); 
 954         if(encryptKeyChainName
) { 
 955                 encryptCerts 
= getSslCerts(encryptKeyChainName
, true, completeCertChain
, 
 956                         anchorFile
, &encryptKc
); 
 957                 if(encryptCerts 
== nil
) { 
 963                 switch(attemptProt
) { 
 965                                 attemptProt 
= kTLSProtocol1Only
; 
 968                                 attemptProt 
= kSSLProtocol3Only
; 
 976                 int r 
= cspReadFile(dhParamsFile
, &dhParams
, &dhParamsLen
); 
 978                         printf("***Error reading diffie-hellman params from %s; aborting\n", 
 984         /* one-time only server port setup */ 
 985         err 
= ListenForClients(portNum
, nonBlocking
, &listenSock
); 
 987         printf("ListenForClients returned %d; aborting\n", (int)err
); 
 991         for(loopNum
=1; ; loopNum
++) { 
 992                 err 
= sslServe(listenSock
, 
1011                         sessionCacheTimeout
, 
1027                         SSLProtocol tryProt 
= attemptProt
; 
1028                         showSSLResult(tryProt
, 
1039                                 fileBase 
? fullFileBase 
: NULL
); 
1041                 errCount 
+= verifyClientCertState(vfyCertState
, expectCertState
, 
1043                 freePeerCerts(peerCerts
); 
1044                 if(loops 
&& (loopNum 
== loops
)) { 
1049         endpointShutdown(listenSock
); 
1052                 CFRelease(serverKc
); 
1055                 CFRelease(encryptKc
);