X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/Security/libsecurity_ssl/sslViewer/sslServer.cpp?ds=sidebyside diff --git a/Security/libsecurity_ssl/sslViewer/sslServer.cpp b/Security/libsecurity_ssl/sslViewer/sslServer.cpp deleted file mode 100644 index c8fe63e3..00000000 --- a/Security/libsecurity_ssl/sslViewer/sslServer.cpp +++ /dev/null @@ -1,1061 +0,0 @@ -/* - * Copyright (c) 2008-2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * Trivial SSL server example, using SecureTransport / OS X version. - * - */ - -#include -#include -#include "sslAppUtils.h" -#include "ioSock.h" -#include "fileIo.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include "printCert.h" - -#if NO_SERVER -#include -#endif - -/* Set true when PR-3074739 is merged to TOT */ -#define SET_DH_PARAMS_ENABLE 1 - -/* true when using SSLCopyPeerCertificates() per Radar 3311892 */ -#define USE_COPY_PEER_CERTS 1 - -/* - * Defaults, overridable by user. - */ -#define SERVER_MESSAGE "HTTP/1.0 200 OK\015\012Content-Type: text/html\015\012\015\012" \ - "SecureTransport Test Server" \ - "

Secure connection established.

" \ - "Message from the 'sslServer' sample application.\015\012" \ - "\015\012" - -/* For ease of debugging, pick a non-privileged port */ -#define DEFAULT_PORT 1200 -// #define DEFAULT_PORT 443 - -#define DEFAULT_HOST "localhost" - -#define DEFAULT_KC "certkc" - -static void usage(char **argv) -{ - printf("Usage: %s [option ...]\n", argv[0]); - printf("Options:\n"); - printf(" P=port Port to listen on; default is %d\n", DEFAULT_PORT); - printf(" k=keychain Contains server cert and keys.\n"); - printf(" y=keychain Encryption-only cert and keys.\n"); - printf(" e Allow Expired Certs\n"); - printf(" r Allow any root cert\n"); - printf(" E Allow Expired Roots\n"); - printf(" x Disable Cert Verification\n"); - printf(" f=fileBase Write Peer Certs to fileBase*\n"); - printf(" c Display peer certs\n"); - printf(" d Display received data\n"); - printf(" C=cipherSuite (e=40-bit d=DES D=40-bit DES 3=3DES 4=RC4 $=40-bit RC4\n" - " 2=RC2 a=AES128 A=AES256 h=DH H=Anon DH r=DHE/RSA s=DH/DSS\n" - " n=RSA/NULL\n"); - printf(" 2 SSLv2 only (default is best fit)\n"); - printf(" 3 SSLv3 only (default is best fit)\n"); - printf(" t TLSv1 only (default is best fit)\n"); - printf(" o TLSv1, SSLv3 use kSSLProtocol__X__Only\n"); - printf(" g={prot...} Specify legal protocols; prot = any combo of [23t]\n"); - printf(" T=[nrsj] Verify client cert state = " - "none/requested/sent/rejected\n"); - printf(" R Disable resumable session support\n"); - printf(" i=timeout Session cache timeout\n"); - printf(" u=[nat] Authentication: n=never; a=always; t=try\n"); - printf(" b Non-blocking I/O\n"); - printf(" a fileNmae Add fileName to list of trusted roots\n"); - printf(" A fileName fileName is ONLY trusted root\n"); - printf(" U filename Add filename to acceptable DNList (multiple times OK)\n"); - printf(" D filename Diffie-Hellman parameters from filename\n"); - printf(" z=password Unlock server keychain with password.\n"); - printf(" H Do SecIdentityRef search instead of specific keychain\n"); - printf(" M Complete cert chain (default assumes that our identity is root)\n"); - printf(" 4 Disable anonymous ciphers\n"); - printf(" p Pause after each phase\n"); - printf(" l[=loops] Loop, performing multiple transactions\n"); - printf(" q Quiet/diagnostic mode (site names and errors only)\n"); - printf(" h Help\n"); - exit(1); -} - -/* snag a copy of current connection's peer certs so we can - * examine them later after the connection is closed */ -static OSStatus copyPeerCerts( - SSLContext *ctx, - CFArrayRef *peerCerts) // mallocd & RETURNED -{ - #if USE_COPY_PEER_CERTS - OSStatus ortn = SSLCopyPeerCertificates(ctx, peerCerts); - #else - OSStatus ortn = SSLGetPeerCertificates(ctx, peerCerts); - #endif - if(ortn) { - printf("***Error obtaining peer certs: %s\n", - sslGetSSLErrString(ortn)); - } - return ortn; -} - -/* free the cert array obtained via SSLGetPeerCertificates() */ -static void freePeerCerts( - CFArrayRef peerCerts) -{ - if(peerCerts == NULL) { - return; - } - - #if USE_COPY_PEER_CERTS - - /* Voila! Problem fixed. */ - CFRelease(peerCerts); - return; - - #else - - CFIndex numCerts; - SecCertificateRef certData; - CFIndex i; - - numCerts = CFArrayGetCount(peerCerts); - for(i=0; i", ((unsigned)c) & 0xff); - } - break; - } - - } - printf("\n"); -} - -static void doPause(const char *prompt) { - if(prompt) { - printf("%s. ", prompt); - } - fpurge(stdin); - printf("Continue (n/anything)? "); - char c = getchar(); - if(c == 'n') { - exit(0); - } -} - -/* - * Perform one SSL diagnostic server-side session. Returns nonzero on error. - * Normally no output to stdout except initial "waiting for connection" message, - * unless there is a really screwed up error (i.e., something not directly related - * to the SSL connection). - */ -#define RCV_BUF_SIZE 256 - -static OSStatus sslServe( - otSocket listenSock, - unsigned short portNum, - SSLProtocol tryVersion, // only used if acceptedProts NULL - const char *acceptedProts, - CFArrayRef serverCerts, // required - char *password, // optional - CFArrayRef encryptServerCerts, // optional - bool allowExpired, - bool allowAnyRoot, - bool allowExpiredRoot, - bool disableCertVerify, - char *anchorFile, - bool replaceAnchors, - char cipherRestrict, // '2', 'd'. etc...'\0' for no - // restriction - SSLAuthenticate authenticate, - unsigned char *dhParams, // optional D-H parameters - unsigned dhParamsLen, - CFArrayRef acceptableDNList, // optional - bool resumableEnable, - uint32_t sessionCacheTimeout,// optional - bool disableAnonCiphers, - bool silent, // no stdout - bool pause, - SSLProtocol *negVersion, // RETURNED - SSLCipherSuite *negCipher, // RETURNED - SSLClientCertificateState *certState, // RETURNED - Boolean *sessionWasResumed, // RETURNED - unsigned char *sessionID, // mallocd by caller, RETURNED - size_t *sessionIDLength, // RETURNED - CFArrayRef *peerCerts, // mallocd & RETURNED - char **argv) -{ - otSocket acceptSock; - PeerSpec peerId; - OSStatus ortn; - SSLContextRef ctx = NULL; - size_t length; - uint8_t rcvBuf[RCV_BUF_SIZE]; - const char *outMsg = SERVER_MESSAGE; - - *negVersion = kSSLProtocolUnknown; - *negCipher = SSL_NULL_WITH_NULL_NULL; - *peerCerts = NULL; - - #if IGNORE_SIGPIPE - signal(SIGPIPE, sigpipe); - #endif - - /* first wait for a connection */ - if(!silent) { - printf("Waiting for client connection on port %u...", portNum); - fflush(stdout); - } - ortn = AcceptClientConnection(listenSock, &acceptSock, &peerId); - if(ortn) { - printf("AcceptClientConnection returned %d; aborting\n", (int)ortn); - return ortn; - } - - /* - * Set up a SecureTransport session. - * First the standard calls. - */ - ortn = SSLNewContext(true, &ctx); - if(ortn) { - printSslErrStr("SSLNewContext", ortn); - goto cleanup; - } - ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite); - if(ortn) { - printSslErrStr("SSLSetIOFuncs", ortn); - goto cleanup; - } - ortn = SSLSetConnection(ctx, (SSLConnectionRef)acceptSock); - if(ortn) { - printSslErrStr("SSLSetConnection", ortn); - goto cleanup; - } - - /* have to do these options befor setting server certs */ - if(allowExpired) { - ortn = SSLSetAllowsExpiredCerts(ctx, true); - if(ortn) { - printSslErrStr("SSLSetAllowExpiredCerts", ortn); - goto cleanup; - } - } - if(allowAnyRoot) { - ortn = SSLSetAllowsAnyRoot(ctx, true); - if(ortn) { - printSslErrStr("SSLSetAllowAnyRoot", ortn); - goto cleanup; - } - } - - if(anchorFile) { - ortn = sslAddTrustedRoot(ctx, anchorFile, replaceAnchors); - if(ortn) { - printf("***Error obtaining anchor file %s\n", anchorFile); - goto cleanup; - } - } - if(serverCerts != NULL) { - if(anchorFile == NULL) { - /* no specific anchors, so assume we want to trust this one */ - ortn = addIdentityAsTrustedRoot(ctx, serverCerts); - if(ortn) { - goto cleanup; - } - } - ortn = SSLSetCertificate(ctx, serverCerts); - if(ortn) { - printSslErrStr("SSLSetCertificate", ortn); - goto cleanup; - } - } - if(encryptServerCerts) { - ortn = SSLSetEncryptionCertificate(ctx, encryptServerCerts); - if(ortn) { - printSslErrStr("SSLSetEncryptionCertificate", ortn); - goto cleanup; - } - } - if(allowExpiredRoot) { - ortn = SSLSetAllowsExpiredRoots(ctx, true); - if(ortn) { - printSslErrStr("SSLSetAllowsExpiredRoots", ortn); - goto cleanup; - } - } - if(disableCertVerify) { - ortn = SSLSetEnableCertVerify(ctx, false); - if(ortn) { - printSslErrStr("SSLSetEnableCertVerify", ortn); - goto cleanup; - } - } - - /* - * SecureTransport options. - */ - if(acceptedProts) { - ortn = SSLSetProtocolVersionEnabled(ctx, kSSLProtocolAll, false); - if(ortn) { - printSslErrStr("SSLSetProtocolVersionEnabled(all off)", ortn); - goto cleanup; - } - for(const char *cp = acceptedProts; *cp; cp++) { - SSLProtocol prot = kSSLProtocolUnknown; - switch(*cp) { - case '2': - prot = kSSLProtocol2; - break; - case '3': - prot = kSSLProtocol3; - break; - case 't': - prot = kTLSProtocol1; - break; - default: - usage(argv); - } - ortn = SSLSetProtocolVersionEnabled(ctx, prot, true); - if(ortn) { - printSslErrStr("SSLSetProtocolVersionEnabled", ortn); - goto cleanup; - } - } - } - else { - ortn = SSLSetProtocolVersion(ctx, tryVersion); - if(ortn) { - printSslErrStr("SSLSetProtocolVersion", ortn); - goto cleanup; - } - } - if(resumableEnable) { - ortn = SSLSetPeerID(ctx, &peerId, sizeof(PeerSpec)); - if(ortn) { - printSslErrStr("SSLSetPeerID", ortn); - goto cleanup; - } - } - if(cipherRestrict != '\0') { - ortn = sslSetCipherRestrictions(ctx, cipherRestrict); - if(ortn) { - goto cleanup; - } - } - if(authenticate != kNeverAuthenticate) { - ortn = SSLSetClientSideAuthenticate(ctx, authenticate); - if(ortn) { - printSslErrStr("SSLSetClientSideAuthenticate", ortn); - goto cleanup; - } - } - if(dhParams) { - ortn = SSLSetDiffieHellmanParams(ctx, dhParams, dhParamsLen); - if(ortn) { - printSslErrStr("SSLSetDiffieHellmanParams", ortn); - goto cleanup; - } - } - if(sessionCacheTimeout) { - ortn = SSLSetSessionCacheTimeout(ctx, sessionCacheTimeout); - if(ortn) { - printSslErrStr("SSLSetSessionCacheTimeout", ortn); - goto cleanup; - } - } - if(disableAnonCiphers) { - ortn = SSLSetAllowAnonymousCiphers(ctx, false); - if(ortn) { - printSslErrStr("SSLSetAllowAnonymousCiphers", ortn); - goto cleanup; - } - /* quickie test of the getter */ - Boolean e; - ortn = SSLGetAllowAnonymousCiphers(ctx, &e); - if(ortn) { - printSslErrStr("SSLGetAllowAnonymousCiphers", ortn); - goto cleanup; - } - if(e) { - printf("***SSLGetAllowAnonymousCiphers() returned true; expected false\n"); - ortn = errSecIO; - goto cleanup; - } - } -/* XXX/cs - if(acceptableDNList) { - ortn = SSLSetCertificateAuthorities(ctx, acceptableDNList, TRUE); - if(ortn) { - printSslErrStr("SSLSetCertificateAuthorities", ortn); - goto cleanup; - } - } -*/ - /* end options */ - - if(pause) { - doPause("SSLContext initialized"); - } - - /* Perform SSL/TLS handshake */ - do - { ortn = SSLHandshake(ctx); - if((ortn == errSSLWouldBlock) && !silent) { - /* keep UI responsive */ - sslOutputDot(); - } - } while (ortn == errSSLWouldBlock); - - /* this works even if handshake failed due to cert chain invalid */ - copyPeerCerts(ctx, peerCerts); - - SSLGetClientCertificateState(ctx, certState); - SSLGetNegotiatedCipher(ctx, negCipher); - SSLGetNegotiatedProtocolVersion(ctx, negVersion); - *sessionIDLength = MAX_SESSION_ID_LENGTH; - SSLGetResumableSessionInfo(ctx, sessionWasResumed, sessionID, - sessionIDLength); - - if(!silent) { - printf("\n"); - } - if(ortn) { - goto cleanup; - } - if(pause) { - doPause("SSLContext handshake complete"); - } - - /* wait for one complete line or user says they've had enough */ - while(ortn == errSecSuccess) { - length = sizeof(rcvBuf); - ortn = SSLRead(ctx, rcvBuf, length, &length); - if(length == 0) { - /* keep UI responsive */ - sslOutputDot(); - } - else { - /* print what we have */ - printf("client request: "); - dumpAscii(rcvBuf, length); - } - if(pause) { - /* allow user to bail */ - char resp; - - fpurge(stdin); - printf("\nMore client request (y/anything): "); - resp = getchar(); - if(resp != 'y') { - break; - } - } - - /* poor person's line completion scan */ - for(unsigned i=0; i SSLSetProtocolVersionEnabled - bool quiet = false; - bool resumableEnable = true; - bool pause = false; - char *keyChainName = NULL; - char *encryptKeyChainName = NULL; - int loops = 1; - SSLAuthenticate authenticate = kNeverAuthenticate; - bool nonBlocking = false; - bool allowExpiredRoot = false; - bool disableCertVerify = false; - char *anchorFile = NULL; - bool replaceAnchors = false; - bool vfyCertState = false; - SSLClientCertificateState expectCertState = kSSLClientCertNone; - char *password = NULL; - char *dhParamsFile = NULL; - unsigned char *dhParams = NULL; - unsigned dhParamsLen = 0; - bool doIdSearch = false; - bool completeCertChain = false; - uint32_t sessionCacheTimeout = 0; - bool disableAnonCiphers = false; - CFMutableArrayRef acceptableDNList = NULL; - - for(arg=1; arg loop forever */ - loops = 0; - break; - } - else if(argp[1] != '=') { - usage(argv); - } - loops = atoi(&argp[2]); - break; - default: - usage(argv); - } - } - -#if NO_SERVER -# if DEBUG - securityd_init(); -# endif -#endif - - /* get server cert and optional encryption cert as CFArrayRef */ - if(keyChainName) { - serverCerts = getSslCerts(keyChainName, false, completeCertChain, - anchorFile, &serverKc); - if(serverCerts == nil) { - exit(1); - } - } - else -#if 0 - if(doIdSearch) { - OSStatus ortn = sslIdentityPicker(NULL, anchorFile, true, NULL, &serverCerts); - if(ortn) { - printf("***IdentitySearch failure; aborting.\n"); - exit(1); - } - } - if(password) { - OSStatus ortn = SecKeychainUnlock(serverKc, strlen(password), password, true); - if(ortn) { - printf("SecKeychainUnlock returned %d\n", (int)ortn); - /* oh well */ - } - } - if(encryptKeyChainName) { - encryptCerts = getSslCerts(encryptKeyChainName, true, completeCertChain, - anchorFile, &encryptKc); - if(encryptCerts == nil) { - exit(1); - } - } -#endif - if(protXOnly) { - switch(attemptProt) { - case kTLSProtocol1: - attemptProt = kTLSProtocol1Only; - break; - case kSSLProtocol3: - attemptProt = kSSLProtocol3Only; - break; - default: - break; - } - } -#if 0 - if(dhParamsFile) { - int r = cspReadFile(dhParamsFile, &dhParams, &dhParamsLen); - if(r) { - printf("***Error reading diffie-hellman params from %s; aborting\n", - dhParamsFile); - } - } -#endif - - /* one-time only server port setup */ - err = ListenForClients(portNum, nonBlocking, &listenSock); - if(err) { - printf("ListenForClients returned %d; aborting\n", (int)err); - exit(1); - } - - for(loopNum=1; ; loopNum++) { - err = sslServe(listenSock, - portNum, - attemptProt, - acceptedProts, - serverCerts, - password, - encryptCerts, - allowExpired, - allowAnyRoot, - allowExpiredRoot, - disableCertVerify, - anchorFile, - replaceAnchors, - cipherRestrict, - authenticate, - dhParams, - dhParamsLen, - acceptableDNList, - resumableEnable, - sessionCacheTimeout, - disableAnonCiphers, - quiet, - pause, - &negVersion, - &negCipher, - &certState, - &sessionWasResumed, - sessionID, - &sessionIDLength, - &peerCerts, - argv); - if(err) { - errCount++; - } - if(!quiet) { - SSLProtocol tryProt = attemptProt; - showSSLResult(tryProt, - acceptedProts, - err, - negVersion, - negCipher, - sessionWasResumed, - sessionID, - sessionIDLength, - peerCerts, - displayCerts, - certState, - fileBase ? fullFileBase : NULL); - } - errCount += verifyClientCertState(vfyCertState, expectCertState, - certState); - freePeerCerts(peerCerts); - if(loops && (loopNum == loops)) { - break; - } - }; - - endpointShutdown(listenSock); - - if(serverKc) { - CFRelease(serverKc); - } - if(encryptKc) { - CFRelease(encryptKc); - } - return errCount; - -} - -