X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/427c49bcad63d042b29ada2ac27e3dfc4845c779..e3d3b979fd185d8303f28a937baa53a187fb8c7d:/libsecurity_ssl/lib/sslCert.c?ds=sidebyside diff --git a/libsecurity_ssl/lib/sslCert.c b/libsecurity_ssl/lib/sslCert.c index 081e8726..4aee2efb 100644 --- a/libsecurity_ssl/lib/sslCert.c +++ b/libsecurity_ssl/lib/sslCert.c @@ -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,38 +155,23 @@ 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 errSecAllocate; - } - if ((err = SSLAllocBuffer(&cert->derCert, certLen) - { 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 errSecAllocate; } - if (ctx->peerCert) { - sslDebugLog("SSLProcessCertificate: releasing existing cert chain\n"); - CFRelease(ctx->peerCert); - } - ctx->peerCert = certChain; } cert = SecCertificateCreateWithBytes(NULL, p, certLen); #if SSL_DEBUG && !TARGET_OS_IPHONE @@ -212,11 +193,28 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx) /* 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) && @@ -241,6 +239,8 @@ SSLProcessCertificate(SSLBuffer message, SSLContext *ctx) } } + + if((err = sslVerifyCertChain(ctx, ctx->peerCert, true)) != 0) { AlertDescription desc; switch(err) {