X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/fa7225c82381bac4432a6edf16f53b5370238d85..7e6b461318c8a779d91381531435a68ee4e8b6ed:/sslViewer/SSLViewer.c diff --git a/sslViewer/SSLViewer.c b/sslViewer/SSLViewer.c index ad71321a..3cd0381e 100644 --- a/sslViewer/SSLViewer.c +++ b/sslViewer/SSLViewer.c @@ -23,7 +23,7 @@ #include "utilities/fileIo.h" #include "utilities/SecCFWrappers.h" #include "utilities/SecIOFormat.h" -#include "SecurityTool/print_cert.h" +#include "SecurityTool/sharedTool/print_cert.h" #define DEFAULT_GETMSG "GET" #define DEFAULT_PATH "/" @@ -32,6 +32,7 @@ #define DEFAULT_HOST "www.amazon.com" #define DEFAULT_PORT 443 +static const int _maxFileStringSize = 100; static void usageNorm(char **argv) { @@ -57,7 +58,7 @@ static void usageNorm(char **argv) " [23t]\n"); printf(" k=keychain Contains cert and keys. Optional.\n"); printf(" l=loopCount Perform loopCount ops (default = 1)\n"); - printf(" P=port Default = %d\n", DEFAULT_PORT); + printf(" P=port Default = %d\n", DEFAULT_PORT); printf(" p Pause after each loop\n"); printf(" q Quiet/diagnostic mode (site names and errors only)\n"); printf(" a fileName Add fileName to list of trusted roots\n"); @@ -111,7 +112,7 @@ static void usage(char **argv) exit(1); } -/* +/* * Arguments to top-level sslPing() */ typedef struct { @@ -123,18 +124,18 @@ typedef struct { const char *vfyHostName; // use this for cert vfy if non-NULL, // else use hostName unsigned short port; - const char *getMsg; // e.g., - // "GET / HTTP/1.0\r\n\r\n" + const char *getMsg; // e.g., + // "GET / HTTP/1.0\r\n\r\n" bool allowExpired; bool allowAnyRoot; bool allowExpiredRoot; bool disableCertVerify; bool manualCertVerify; bool dumpRxData; // display server data - char cipherRestrict; // '2', 'd'. etc...; '\0' for + char cipherRestrict; // '2', 'd'. etc...; '\0' for // no restriction bool keepConnected; - bool requireNotify; // require closure notify + bool requireNotify; // require closure notify // in V3 mode bool resumableEnable; bool allowHostnameSpoof; @@ -167,7 +168,7 @@ typedef struct { static void sigpipe(int sig) -{ +{ fflush(stdin); printf("***SIGPIPE***\n"); } @@ -191,7 +192,7 @@ static OSStatus sslEvaluateTrust( return ortn; } if(secTrust == NULL) { - /* this is the normal case for resumed sessions, in which + /* this is the normal case for resumed sessions, in which * no cert evaluation is performed */ if(!pargs->silent) { printf("...No SecTrust available - this is a resumed session, right?\n"); @@ -205,7 +206,7 @@ static OSStatus sslEvaluateTrust( } SecTrustResultType secTrustResult; - ortn = SecTrustEvaluate(secTrust, &secTrustResult); + ortn = SecTrustGetTrustResult(secTrust, &secTrustResult); // implicitly does trust evaluate if(ortn) { printf("\n***Error on SecTrustEvaluate: %d\n", (int)ortn); return ortn; @@ -213,31 +214,26 @@ static OSStatus sslEvaluateTrust( if(pargs->verbose) { const char *res = NULL; switch(secTrustResult) { - case kSecTrustResultInvalid: + case kSecTrustResultInvalid: res = "kSecTrustResultInvalid"; break; - case kSecTrustResultProceed: + case kSecTrustResultProceed: res = "kSecTrustResultProceed"; break; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - case kSecTrustResultConfirm: -#pragma clang diagnostic pop - res = "kSecTrustResultConfirm"; break; case kSecTrustResultDeny: res = "kSecTrustResultDeny"; break; - case kSecTrustResultUnspecified: + case kSecTrustResultUnspecified: res = "kSecTrustResultUnspecified"; break; - case kSecTrustResultRecoverableTrustFailure: + case kSecTrustResultRecoverableTrustFailure: res = "kSecTrustResultRecoverableTrustFailure"; break; - case kSecTrustResultFatalTrustFailure: + case kSecTrustResultFatalTrustFailure: res = "kSecTrustResultFatalTrustFailure"; break; - case kSecTrustResultOtherError: + case kSecTrustResultOtherError: res = "kSecTrustResultOtherError"; break; default: res = "UNKNOWN"; break; } printf("\nSecTrustEvaluate(): secTrustResult %s\n", res); } - + switch(secTrustResult) { case kSecTrustResultUnspecified: /* cert chain valid, no special UserTrust assignments */ @@ -245,7 +241,7 @@ static OSStatus sslEvaluateTrust( /* cert chain valid AND user explicitly trusts this */ break; default: - printf("\n***SecTrustEvaluate reported secTrustResult %d\n", + printf("\n***SecTrustEvaluate reported secTrustResult %d\n", (int)secTrustResult); ortn = errSSLXCertChainInvalid; break; @@ -277,13 +273,13 @@ static OSStatus sslEvaluateTrust( /* print reply received from server, safely */ static void dumpAscii( - uint8_t *rcvBuf, + uint8_t *rcvBuf, size_t len) { char *cp = (char *)rcvBuf; uint32_t i; char c; - + for(i=0; inegVersion = kSSLProtocolUnknown; pargs->negCipher = SSL_NULL_WITH_NULL_NULL; pargs->peerCerts = NULL; - + /* first make sure requested server is there */ ortn = MakeServerConnection(pargs->hostName, pargs->port, pargs->nonBlocking, &sock, &peerId); @@ -357,8 +353,8 @@ static OSStatus sslPing( if(pargs->verbose) { printf("...connected to server; starting SecureTransport\n"); } - - /* + + /* * Set up a SecureTransport session. * First the standard calls. */ @@ -366,12 +362,12 @@ static OSStatus sslPing( if(ctx == NULL) { printf("SSLCreateContext\n"); goto cleanup; - } + } ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite); if(ortn) { printSslErrStr("SSLSetIOFuncs", ortn); goto cleanup; - } + } ortn = SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock); if(ortn) { printSslErrStr("SSLSetConnection", ortn); @@ -386,7 +382,7 @@ static OSStatus sslPing( if(getConn != (SSLConnectionRef)(intptr_t)sock) { printf("***SSLGetConnection error\n"); ortn = errSecParam; - goto cleanup; + goto cleanup; } if(!pargs->allowHostnameSpoof) { /* if this isn't set, it isn't checked by AppleX509TP */ @@ -401,62 +397,46 @@ static OSStatus sslPing( goto cleanup; } } - - /* + + /* * SecureTransport options. - */ + */ if(pargs->acceptedProts) { - ortn = SSLSetProtocolVersionEnabled(ctx, kSSLProtocolAll, false); if(ortn) { printSslErrStr("SSLSetProtocolVersionEnabled(all off)", ortn); goto cleanup; } for(const char *cp = pargs->acceptedProts; *cp; cp++) { - SSLProtocol prot; switch(*cp) { case '2': - prot = kSSLProtocol2; + ortn = SSLSetProtocolVersionMax(ctx, kSSLProtocol2); break; case '3': - prot = kSSLProtocol3; + ortn = SSLSetProtocolVersionMax(ctx, kSSLProtocol3); break; case 't': - prot = kTLSProtocol12; + ortn = SSLSetProtocolVersionMax(ctx, kTLSProtocol12); break; default: usage(pargs->argv); } - ortn = SSLSetProtocolVersionEnabled(ctx, prot, true); if(ortn) { - printSslErrStr("SSLSetProtocolVersionEnabled", ortn); + printSslErrStr("SSLSetProtocolVersionMax", ortn); goto cleanup; } } + } else { + ortn = SSLSetProtocolVersionMax(ctx, pargs->tryVersion); + if(ortn) { + printSslErrStr("SSLSetProtocolVersionMax", ortn); + goto cleanup; + } } - else { - ortn = SSLSetProtocolVersion(ctx, pargs->tryVersion); - if(ortn) { - printSslErrStr("SSLSetProtocolVersion", ortn); - goto cleanup; - } - SSLProtocol getVers; - ortn = SSLGetProtocolVersion(ctx, &getVers); - if(ortn) { - printSslErrStr("SSLGetProtocolVersion", ortn); - goto cleanup; - } - if(getVers != pargs->tryVersion) { - printf("***SSLGetProtocolVersion screwup: try %s get %s\n", - sslGetProtocolVersionString(pargs->tryVersion), - sslGetProtocolVersionString(getVers)); - ortn = errSecParam; - goto cleanup; - } - } + if(pargs->resumableEnable) { const void *rtnId = NULL; size_t rtnIdLen = 0; - + ortn = SSLSetPeerID(ctx, &peerId, sizeof(PeerSpec)); if(ortn) { printSslErrStr("SSLSetPeerID", ortn); @@ -558,16 +538,16 @@ static OSStatus sslPing( } /*** end options ***/ - + if(pargs->verbose) { printf("...starting SSL handshake\n"); } startHandshake = CFAbsoluteTimeGetCurrent(); - + do { ortn = SSLHandshake(ctx); if((ortn == errSSLWouldBlock) && !pargs->silent) { - /* keep UI responsive */ + /* keep UI responsive */ sslOutputDot(); } } while (ortn == errSSLWouldBlock); @@ -583,7 +563,7 @@ static OSStatus sslPing( pargs->handshakeTimeTotal += pargs->handshakeTimeOp; } pargs->numHandshakes++; - + ortn = SSLCopyPeerTrust(ctx, &pargs->peerTrust); if(ortn) { printf("***SSLCopyPeerTrust error %" PRIdOSStatus "\n", ortn); @@ -595,10 +575,8 @@ static OSStatus sslPing( SSLGetNegotiatedCipher(ctx, &pargs->negCipher); SSLGetNegotiatedProtocolVersion(ctx, &pargs->negVersion); pargs->sessionIDLength = MAX_SESSION_ID_LENGTH; - SSLGetResumableSessionInfo(ctx, &pargs->sessionWasResumed, pargs->sessionID, - &pargs->sessionIDLength); - - { + ortn = SSLGetResumableSessionInfo(ctx, &pargs->sessionWasResumed, pargs->sessionID, &pargs->sessionIDLength); + if(!ortn) { OSStatus certRtn = sslEvaluateTrust(ctx, pargs, &pargs->peerCerts); if (certRtn && !pargs->manualCertVerify) { @@ -610,7 +588,7 @@ static OSStatus sslPing( ortn = certRtn; } } - + if(ortn) { if(!pargs->silent) { printf("\n"); @@ -624,15 +602,15 @@ static OSStatus sslPing( length = strlen(pargs->getMsg); (void) SSLWrite(ctx, pargs->getMsg, length, &actLen); - /* + /* * Try to snag RCV_BUF_SIZE bytes. Exit if (!keepConnected and we get any data * at all), or (keepConnected and err != (none, wouldBlock)). */ - while (1) { + while (1) { actLen = 0; if(pargs->dumpRxData) { size_t avail = 0; - + ortn = SSLGetBufferedReadSize(ctx, &avail); if(ortn) { printf("***SSLGetBufferedReadSize error\n"); @@ -673,7 +651,7 @@ static OSStatus sslPing( SSLGetClientCertificateState(ctx, &pargs->certState); SSLGetNegotiatedCipher(ctx, &pargs->negCipher); SSLGetNegotiatedProtocolVersion(ctx, &pargs->negVersion); - + /* convert normal "shutdown" into zero err rtn */ if(ortn == errSSLClosedGraceful) { ortn = errSecSuccess; @@ -684,9 +662,12 @@ static OSStatus sslPing( } cleanup: ; /* - * always do close, even on error - to flush outgoing write queue + * always do close, even on error - to flush outgoing write queue */ - OSStatus cerr = SSLClose(ctx); + OSStatus cerr = errSecParam; + if (ctx) { + cerr = SSLClose(ctx); + } if(ortn == errSecSuccess) { ortn = cerr; } @@ -695,7 +676,7 @@ cleanup: ; } if(ctx) { CFRelease(ctx); - } + } return ortn; } @@ -825,7 +806,7 @@ static void showPeerCerts( CFIndex numCerts; SecCertificateRef certRef; CFIndex i; - + if(peerCerts == NULL) { return; } @@ -846,14 +827,14 @@ static void writePeerCerts( CFIndex numCerts; SecCertificateRef certRef; CFIndex i; - char fileName[100]; - + char fileName[_maxFileStringSize]; + if(peerCerts == NULL) { return; } numCerts = CFArrayGetCount(peerCerts); for(i=0; iacceptedProts) { printf(" Allowed SSL versions : %s\n", pargs->acceptedProts); } else { - printf(" Attempted SSL version : %s\n", + printf(" Attempted SSL version : %s\n", sslGetProtocolVersionString(pargs->tryVersion)); } - + printf(" Result : %s\n", sslGetSSLErrString(err)); - printf(" Negotiated SSL version : %s\n", + printf(" Negotiated SSL version : %s\n", sslGetProtocolVersionString(pargs->negVersion)); printf(" Negotiated CipherSuite : %s\n", sslGetCipherSuiteString(pargs->negCipher)); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" if(pargs->certState != kSSLClientCertNone) { printf(" Client Cert State : %s\n", sslGetClientCertStateString(pargs->certState)); } +#pragma clang diagnostic pop if(pargs->verbose) { printf(" Resumed Session : "); if(pargs->sessionWasResumed) { @@ -941,7 +925,7 @@ static void showSSLResult( writePeerCerts(pargs->peerCerts, fileBase); } } - + printf("\n"); } @@ -990,6 +974,8 @@ static SSLProtocol charToProt( char c, // 2, 3, t char **argv) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" switch(c) { case '2': return kSSLProtocol2; @@ -1000,17 +986,16 @@ static SSLProtocol charToProt( default: usage(argv); } - /* NOT REACHED */ - return kSSLProtocolUnknown; +#pragma clang diagnostic pop } int main(int argc, char **argv) -{ +{ OSStatus err; int arg; char *argp; char getMsg[300]; - char fullFileBase[100]; + char fullFileBase[_maxFileStringSize]; int ourRtn = 0; // exit status - sum of all errors unsigned loop; SecKeychainRef serverKc = nil; @@ -1031,15 +1016,17 @@ int main(int argc, char **argv) bool doPause = false; bool pauseFirstLoop = false; bool verifyProt = false; - SSLProtocol maxProtocol = kTLSProtocol12; // for verifying negotiated - // protocol char *acceptedProts = NULL; char *keyChainName = NULL; char *getMsgSpec = NULL; bool vfyCertState = false; - SSLClientCertificateState expectCertState = kSSLClientCertNone; bool displayHandshakeTimes = false; bool completeCertChain = false; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + SSLClientCertificateState expectCertState = kSSLClientCertNone; + SSLProtocol maxProtocol = kTLSProtocol12; // for verifying negotiated protocol +#pragma clang diagnostic pop /* special case - one arg of "h" or "-h" or "hv" */ if(argc == 2) { @@ -1050,14 +1037,14 @@ int main(int argc, char **argv) usageVerbose(argv); } } - + /* set up defaults */ memset(&pargs, 0, sizeof(sslPingArgs)); pargs.hostName = DEFAULT_HOST; pargs.port = DEFAULT_PORT; pargs.resumableEnable = true; pargs.argv = argv; - + for(arg=1; arg 1) ? "errors" : "error", pargs.hostName); } return ourRtn; } - -