#include <CoreFoundation/CoreFoundation.h>
#include <Security/SecCertificate.h>
#include <Security/SecCertificatePriv.h>
-#include <Security/SecInternal.h>
#include <Security/oidsalg.h>
+#include "utilities/SecCFRelease.h"
OSStatus
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);
if(certCount == 0) {
sslCertDebug("...sending empty cert msg");
}
- return noErr;
+ return errSecSuccess;
}
OSStatus
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);
}
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) &&
* we tried to authenticate, client doesn't have a cert, and
* app doesn't require it. OK.
*/
- return noErr;
+ return errSecSuccess;
}
else {
AlertDescription desc;
}
}
+
+
if((err = sslVerifyCertChain(ctx, ctx->peerCert, true)) != 0) {
AlertDescription desc;
switch(err) {
SSLFatalSessionAlert(desc, ctx);
}
- if (err == noErr) {
+ if (err == errSecSuccess) {
if(ctx->peerPubKey != NULL) {
/* renegotiating - free old key first */
sslFreePubKey(&ctx->peerPubKey);
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);
}
assert(charPtr == request->contents.data + request->contents.length);
- return noErr;
+ return errSecSuccess;
}
#define SSL_ENABLE_ECDSA_SIGN_AUTH 0
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);
assert(charPtr == message.data + message.length);
- return noErr;
+ return errSecSuccess;
}
//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
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 */
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:
assert(charPtr==(certVerify->contents.data+head));
- err = noErr;
+ err = errSecSuccess;
fail:
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;
SSLFatalSessionAlert(SSL_AlertDecryptError, ctx);
goto fail;
}
- err = noErr;
+ err = errSecSuccess;
fail:
return err;