X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195..e3d3b979fd185d8303f28a937baa53a187fb8c7d:/libsecurity_ssl/lib/sslCert.c?ds=inline diff --git a/libsecurity_ssl/lib/sslCert.c b/libsecurity_ssl/lib/sslCert.c index 85c58b6e..4aee2efb 100644 --- a/libsecurity_ssl/lib/sslCert.c +++ b/libsecurity_ssl/lib/sslCert.c @@ -40,8 +40,8 @@ #include #include #include -#include #include +#include "utilities/SecCFRelease.h" OSStatus @@ -89,7 +89,7 @@ SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx) certificate->contentType = SSL_RecordTypeHandshake; certificate->protocolVersion = ctx->negProtocolVersion; head = SSLHandshakeHeaderSize(certificate); - if ((err = SSLAllocBuffer(&certificate->contents, totalLength + head + 3, ctx)) != 0) + if ((err = SSLAllocBuffer(&certificate->contents, totalLength + head + 3))) return err; charPtr = SSLEncodeHandshakeHeader(ctx, certificate, SSL_HdskCert, totalLength+3); @@ -134,7 +134,7 @@ SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx) if(certCount == 0) { sslCertDebug("...sending empty cert msg"); } - return noErr; + return errSecSuccess; } OSStatus @@ -143,12 +143,8 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx) size_t listLen, certLen; UInt8 *p; OSStatus err; -#ifdef USE_SSLCERTIFICATE - SSLCertificate *cert; -#else CFMutableArrayRef certChain = NULL; SecCertificateRef cert; -#endif p = message.data; listLen = SSLDecodeInt(p,3); @@ -159,64 +155,66 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx) } while (listLen > 0) - { certLen = SSLDecodeInt(p,3); + { + if (listLen < 3) { + sslErrorLog("SSLProcessCertificate: length decode error 2\n"); + return errSSLProtocol; + } + certLen = SSLDecodeInt(p,3); p += 3; if (listLen < certLen + 3) { - sslErrorLog("SSLProcessCertificate: length decode error 2\n"); + sslErrorLog("SSLProcessCertificate: length decode error 3\n"); return errSSLProtocol; } -#ifdef USE_SSLCERTIFICATE - cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate)); - if(cert == NULL) { - return memFullErr; - } - if ((err = SSLAllocBuffer(&cert->derCert, certLen, ctx)) != 0) - { sslFree(cert); - return err; - } - memcpy(cert->derCert.data, p, certLen); - p += certLen; - cert->next = ctx->peerCert; /* Insert backwards; root cert - * will be first in linked list */ - ctx->peerCert = cert; -#else if (!certChain) { certChain = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); if (certChain == NULL) { - return memFullErr; - } - if (ctx->peerCert) { - sslDebugLog("SSLProcessCertificate: releasing existing cert chain\n"); - CFRelease(ctx->peerCert); + return errSecAllocate; } - ctx->peerCert = certChain; } cert = SecCertificateCreateWithBytes(NULL, p, certLen); - #if SSL_DEBUG + #if SSL_DEBUG && !TARGET_OS_IPHONE { /* print cert name when debugging; leave disabled otherwise */ CFStringRef certName = NULL; OSStatus status = SecCertificateInferLabel(cert, &certName); char buf[1024]; - if (!certName || !CFStringGetCString(certName, buf, 1024-1, kCFStringEncodingUTF8)) { buf[0]=0; } - sslDebugLog("SSLProcessCertificate: received \"%s\" (%ld bytes)\n", buf, certLen); + if (status || !certName || !CFStringGetCString(certName, buf, 1024-1, kCFStringEncodingUTF8)) { buf[0]=0; } + sslDebugLog("SSLProcessCertificate: err=%d, received \"%s\" (%ld bytes)\n",(int) status, buf, certLen); CFReleaseSafe(certName); } #endif if (cert == NULL) { sslErrorLog("SSLProcessCertificate: unable to create cert ref from data\n"); - return memFullErr; + return errSecAllocate; } p += certLen; /* Insert forwards; root cert will be last in linked list */ CFArrayAppendValue(certChain, cert); CFRelease(cert); -#endif listLen -= 3+certLen; } assert(p == message.data + message.length && listLen == 0); + if (ctx->protocolSide == kSSLClientSide && ctx->peerCert && !ctx->allowServerIdentityChange) { + // Do not accept a different server cert during renegotiation unless allowed. + if((certChain!=NULL) && !CFEqual(ctx->peerCert, certChain)) + { + CFRelease(certChain); + sslErrorLog("Illegal server identity change during renegotiation\n"); + return errSSLProtocol; + } + } + + // Replace old cert with new cert. + if (ctx->peerCert) { + sslDebugLog("SSLProcessCertificate: releasing existing cert chain\n"); + CFRelease(ctx->peerCert); + } + + ctx->peerCert = certChain; + if (!ctx->peerCert) { /* this *might* be OK... */ if((ctx->protocolSide == kSSLServerSide) && @@ -225,7 +223,7 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx) * we tried to authenticate, client doesn't have a cert, and * app doesn't require it. OK. */ - return noErr; + return errSecSuccess; } else { AlertDescription desc; @@ -241,6 +239,8 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx) } } + + if((err = sslVerifyCertChain(ctx, ctx->peerCert, true)) != 0) { AlertDescription desc; switch(err) { @@ -260,7 +260,7 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx) SSLFatalSessionAlert(desc, ctx); } - if (err == noErr) { + if (err == errSecSuccess) { if(ctx->peerPubKey != NULL) { /* renegotiating - free old key first */ sslFreePubKey(&ctx->peerPubKey); @@ -343,7 +343,7 @@ SSLEncodeCertificateRequest(SSLRecord *request, SSLContext *ctx) request->protocolVersion = ctx->negProtocolVersion; head = SSLHandshakeHeaderSize(request); - if ((err = SSLAllocBuffer(&request->contents, msgLen + head, ctx)) != 0) + if ((err = SSLAllocBuffer(&request->contents, msgLen + head))) return err; charPtr = SSLEncodeHandshakeHeader(ctx, request, SSL_HdskCertRequest, msgLen); @@ -392,7 +392,7 @@ SSLEncodeCertificateRequest(SSLRecord *request, SSLContext *ctx) } assert(charPtr == request->contents.data + request->contents.length); - return noErr; + return errSecSuccess; } #define SSL_ENABLE_ECDSA_SIGN_AUTH 0 @@ -492,11 +492,11 @@ SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx) sslErrorLog("SSLProcessCertificateRequest: dnListLen error 2\n"); return errSSLProtocol; } - if ((err = SSLAllocBuffer(&dnBuf, sizeof(DNListElem), ctx)) != 0) + if ((err = SSLAllocBuffer(&dnBuf, sizeof(DNListElem)))) return err; dn = (DNListElem*)dnBuf.data; - if ((err = SSLAllocBuffer(&dn->derDN, dnLen, ctx)) != 0) - { SSLFreeBuffer(&dnBuf, ctx); + if ((err = SSLAllocBuffer(&dn->derDN, dnLen))) + { SSLFreeBuffer(&dnBuf); return err; } memcpy(dn->derDN.data, charPtr, dnLen); @@ -508,7 +508,7 @@ SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx) assert(charPtr == message.data + message.length); - return noErr; + return errSecSuccess; } @@ -536,7 +536,7 @@ OSStatus FindCertSigAlg(SSLContext *ctx, //Let's only support SHA1 and SHA256. SHA384 does not work with 512 bits RSA keys // We should actually test against what the client cert can do. if((alg->hash==SSL_HashAlgorithmSHA1) || (alg->hash==SSL_HashAlgorithmSHA256)) { - return noErr; + return errSecSuccess; } } // We could not find a supported signature and hash algorithm @@ -600,7 +600,7 @@ SSLEncodeCertificateVerify(SSLRecord *certVerify, SSLContext *ctx) if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, &hashDataBuf, sigAlg.hash)) != 0) goto fail; - if ((err = SSLAllocBuffer(&certVerify->contents, outputLen, ctx)) != 0) + if ((err = SSLAllocBuffer(&certVerify->contents, outputLen)) != 0) goto fail; /* Sign now to get the actual length */ @@ -652,7 +652,7 @@ SSLEncodeCertificateVerify(SSLRecord *certVerify, SSLContext *ctx) len = outputLen+2; } if(err) { - sslErrorLog("SSLEncodeCertificateVerify: unable to sign data (error %d)\n", err); + sslErrorLog("SSLEncodeCertificateVerify: unable to sign data (error %d)\n", (int)err); goto fail; } // At this point: @@ -666,7 +666,7 @@ SSLEncodeCertificateVerify(SSLRecord *certVerify, SSLContext *ctx) assert(charPtr==(certVerify->contents.data+head)); - err = noErr; + err = errSecSuccess; fail: @@ -700,15 +700,15 @@ SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx) switch (sigAlg.hash) { case SSL_HashAlgorithmSHA256: algId.algorithm = CSSMOID_SHA256WithRSA; - if(ctx->selectedCipherSpec.macAlgorithm->hmac->alg == HA_SHA384) { + if(ctx->selectedCipherSpecParams.macAlg == HA_SHA384) { sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, HA_SHA384\n"); return errSSLInternal; } break; case SSL_HashAlgorithmSHA384: algId.algorithm = CSSMOID_SHA384WithRSA; - if(ctx->selectedCipherSpec.macAlgorithm->hmac->alg != HA_SHA384) { - sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, %d not HA_SHA384\n", ctx->selectedCipherSpec.macAlgorithm->hmac->alg); + if(ctx->selectedCipherSpecParams.macAlg != HA_SHA384) { + sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, %d not HA_SHA384\n", ctx->selectedCipherSpecParams.macAlg); return errSSLInternal; } break; @@ -781,7 +781,7 @@ SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx) SSLFatalSessionAlert(SSL_AlertDecryptError, ctx); goto fail; } - err = noErr; + err = errSecSuccess; fail: return err;