]> git.saurik.com Git - apple/security.git/blobdiff - SecureTransport/sslCert.cpp
Security-222.tar.gz
[apple/security.git] / SecureTransport / sslCert.cpp
diff --git a/SecureTransport/sslCert.cpp b/SecureTransport/sslCert.cpp
deleted file mode 100644 (file)
index 035a898..0000000
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
- * 
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- * 
- * This 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.
- */
-
-
-/*
-       File:           sslCert.cpp
-
-       Contains:       certificate request/verify messages
-
-       Written by:     Doug Mitchell
-
-       Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
-
-*/
-#include "sslContext.h"
-#include "sslHandshake.h"
-#include "sslMemory.h"
-#include "sslAlertMessage.h"
-#include "sslDebug.h"
-#include "sslUtils.h"
-#include "sslDigests.h"
-#include "appleCdsa.h"
-
-#include <string.h>
-#include <assert.h>
-
-OSStatus
-SSLEncodeCertificate(SSLRecord &certificate, SSLContext *ctx)
-{   OSStatus        err;
-    UInt32          totalLength;
-    int             i, j, certCount;
-    UInt8           *charPtr;
-    SSLCertificate  *cert;
-    
-    /* 
-        * TBD: for client side, match Match DER-encoded acceptable DN list
-        * (ctx->acceptableDNList) to one of our certs. For now we just send 
-        * what we have since we don't support multiple certs.
-        *
-        * Note this can be called with localCert==0 for client seide in TLS1;
-        * in that case we send an empty cert msg.
-        */
-    cert = ctx->localCert;
-       assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
-                  (ctx->negProtocolVersion == TLS_Version_1_0));
-       assert((cert != NULL) || (ctx->negProtocolVersion == TLS_Version_1_0));
-    totalLength = 0;
-    certCount = 0;
-    while (cert)
-    {   totalLength += 3 + cert->derCert.length;    /* 3 for encoded length field */
-        ++certCount;
-        cert = cert->next;
-    }
-    
-    certificate.contentType = SSL_RecordTypeHandshake;
-    certificate.protocolVersion = ctx->negProtocolVersion;
-    if ((err = SSLAllocBuffer(certificate.contents, totalLength + 7, ctx)) != 0)
-        return err;
-    
-    charPtr = certificate.contents.data;
-    *charPtr++ = SSL_HdskCert;
-    charPtr = SSLEncodeInt(charPtr, totalLength+3, 3);    /* Handshake message length */
-    charPtr = SSLEncodeInt(charPtr, totalLength, 3);      /* Vector length */
-    
-    /* Root cert is first in the linked list, but has to go last, 
-        * so walk list backwards */
-    for (i = 0; i < certCount; ++i)
-    {   cert = ctx->localCert;
-        for (j = i+1; j < certCount; ++j)
-            cert = cert->next;
-        charPtr = SSLEncodeInt(charPtr, cert->derCert.length, 3);
-        memcpy(charPtr, cert->derCert.data, cert->derCert.length);
-        charPtr += cert->derCert.length;
-    }
-    
-    assert(charPtr == certificate.contents.data + certificate.contents.length);
-    
-    if ((ctx->protocolSide == SSL_ClientSide) && (ctx->localCert)) {
-               /* this tells us to send a CertificateVerify msg after the
-                * client key exchange. We skip the cert vfy if we just
-                * sent an empty cert msg (i.e., we were asked for a cert
-                * but we don't have one). */
-        ctx->certSent = 1;     
-               assert(ctx->clientCertState == kSSLClientCertRequested);
-               assert(ctx->certRequested);
-               ctx->clientCertState = kSSLClientCertSent;
-       }
-    return noErr;
-}
-
-OSStatus
-SSLProcessCertificate(SSLBuffer message, SSLContext *ctx)
-{   OSStatus        err;
-    UInt32          listLen, certLen;
-    UInt8           *p;
-    SSLCertificate  *cert;
-    
-    p = message.data;
-    listLen = SSLDecodeInt(p,3);
-    p += 3;
-    if (listLen + 3 != message.length) {
-       sslErrorLog("SSLProcessCertificate: length decode error 1\n");
-        return errSSLProtocol;
-    }
-    
-    while (listLen > 0)
-    {   certLen = SSLDecodeInt(p,3);
-        p += 3;
-        if (listLen < certLen + 3) {
-               sslErrorLog("SSLProcessCertificate: length decode error 2\n");
-            return errSSLProtocol;
-        }
-               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;
-        listLen -= 3+certLen;
-    }
-    assert(p == message.data + message.length && listLen == 0);
-    
-    if (ctx->peerCert == 0) {
-               /* this *might* be OK... */
-               if((ctx->protocolSide == SSL_ServerSide) &&
-                  (ctx->clientAuth != kAlwaysAuthenticate)) {
-                       /*
-                        * we tried to authenticate, client doesn't have a cert, and 
-                        * app doesn't require it. OK.
-                        */
-                       return noErr;
-               }
-               else {
-                       AlertDescription desc;
-                       if(ctx->negProtocolVersion == SSL_Version_3_0) {
-                               /* this one's for SSL3 only */
-                               desc = SSL_AlertBadCert;
-                       }
-                       else {
-                               desc = SSL_AlertCertUnknown;
-                       }
-                       SSLFatalSessionAlert(desc, ctx);
-                       return errSSLXCertChainInvalid;
-               }
-    }
-    if((err = sslVerifyCertChain(ctx, *ctx->peerCert)) != 0) {
-               AlertDescription desc;
-               switch(err) {
-                       case errSSLUnknownRootCert:
-                       case errSSLNoRootCert:
-                               desc = SSL_AlertUnknownCA;
-                               break;
-                       case errSSLCertExpired:
-                       case errSSLCertNotYetValid:
-                               desc = SSL_AlertCertExpired;
-                               break;
-                       case errSSLXCertChainInvalid:
-                       default:
-                               desc = SSL_AlertCertUnknown;
-                               break;
-               }
-               SSLFatalSessionAlert(desc, ctx);
-        return err;
-       }
-       
-       /* peer's certificate is the last one in the chain */
-    cert = ctx->peerCert;
-    while (cert->next != 0)
-        cert = cert->next;
-       /* Convert its public key to CDSA format */
-    if ((err = sslPubKeyFromCert(ctx, 
-       cert->derCert, 
-       &ctx->peerPubKey,
-       &ctx->peerPubKeyCsp)) != 0)
-        return err;
-        
-    return noErr;
-}
-
-OSStatus
-SSLEncodeCertificateRequest(SSLRecord &request, SSLContext *ctx)
-{   
-       OSStatus    err;
-    UInt32      dnListLen, msgLen;
-    UInt8       *charPtr;
-    DNListElem  *dn;
-    
-       assert(ctx->protocolSide == SSL_ServerSide);
-       dnListLen = 0;
-    dn = ctx->acceptableDNList;
-    while (dn)
-    {   dnListLen += 2 + dn->derDN.length;
-        dn = dn->next;
-    }
-    msgLen = 1 + 1 + 2 + dnListLen;
-    
-    request.contentType = SSL_RecordTypeHandshake;
-       assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
-                  (ctx->negProtocolVersion == TLS_Version_1_0));
-    request.protocolVersion = ctx->negProtocolVersion;
-    if ((err = SSLAllocBuffer(request.contents, msgLen + 4, ctx)) != 0)
-        return err;
-    
-    charPtr = request.contents.data;
-    *charPtr++ = SSL_HdskCertRequest;
-    charPtr = SSLEncodeInt(charPtr, msgLen, 3);
-    
-    *charPtr++ = 1;        /* one cert type */
-    *charPtr++ = 1;        /* RSA-sign type */
-    charPtr = SSLEncodeInt(charPtr, dnListLen, 2);
-    dn = ctx->acceptableDNList;
-    while (dn)
-    {   charPtr = SSLEncodeInt(charPtr, dn->derDN.length, 2);
-        memcpy(charPtr, dn->derDN.data, dn->derDN.length);
-        charPtr += dn->derDN.length;
-        dn = dn->next;
-    }
-    
-    assert(charPtr == request.contents.data + request.contents.length);
-    return noErr;
-}
-
-OSStatus
-SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx)
-{   
-    unsigned        i;
-    unsigned       typeCount;
-    UInt8           *charPtr;
-    
-       /* 
-        * Cert request only happens in during client authentication, which
-        * we don't do. We will however take this handshake msg and do 
-        * nothing with the enclosed DNList. We'll send a client cert
-        * if we have one but we don't do any DNList compare.
-        */
-    if (message.length < 3) {
-       sslErrorLog("SSLProcessCertificateRequest: length decode error 1\n");
-        return errSSLProtocol;
-    }
-    charPtr = message.data;
-    typeCount = *charPtr++;
-    if (typeCount < 1 || message.length < 3 + typeCount) {
-       sslErrorLog("SSLProcessCertificateRequest: length decode error 2\n");
-        return errSSLProtocol;
-    }
-    for (i = 0; i < typeCount; i++)
-    {   if (*charPtr++ == 1)
-            ctx->x509Requested = 1;
-    }
-    
-       #if             0       
-       /* FIXME - currently untested  */
-    unsigned   dnListLen;
-       unsigned        dnLen;
-    SSLBuffer  dnBuf;
-    DNListElem  *dn;
-       OSStatus        err;    
-       
-    dnListLen = SSLDecodeInt(charPtr, 2);
-    charPtr += 2;
-    if (message.length != 3 + typeCount + dnListLen) {
-       sslErrorLog("SSLProcessCertificateRequest: length decode error 3\n");
-        return errSSLProtocol;
-       }    
-    while (dnListLen > 0)
-    {   if (dnListLen < 2) {
-               sslErrorLog("SSLProcessCertificateRequest: dnListLen error 1\n");
-            return errSSLProtocol;
-        }
-        dnLen = SSLDecodeInt(charPtr, 2);
-        charPtr += 2;
-        if (dnListLen < 2 + dnLen) {
-               sslErrorLog("SSLProcessCertificateRequest: dnListLen error 2\n");
-               return errSSLProtocol;
-       }
-        if ((err = SSLAllocBuffer(dnBuf, sizeof(DNListElem), ctx)) != 0)
-            return err;
-        dn = (DNListElem*)dnBuf.data;
-        if ((err = SSLAllocBuffer(dn->derDN, dnLen, ctx)) != 0)
-        {   SSLFreeBuffer(dnBuf, ctx);
-            return err;
-        }
-        memcpy(dn->derDN.data, charPtr, dnLen);
-        charPtr += dnLen;
-        dn->next = ctx->acceptableDNList;
-        ctx->acceptableDNList = dn;
-        dnListLen -= 2 + dnLen;
-    }
-    
-    assert(charPtr == message.data + message.length);
-       #endif  /* untested client-side authentication */
-       
-    return noErr;
-}
-
-OSStatus
-SSLEncodeCertificateVerify(SSLRecord &certVerify, SSLContext *ctx)
-{   OSStatus        err;
-    UInt8           hashData[36];
-    SSLBuffer       hashDataBuf, shaMsgState, md5MsgState;
-    UInt32          len;
-    UInt32                 outputLen;
-    const CSSM_KEY     *cssmKey;
-       
-    certVerify.contents.data = 0;
-    hashDataBuf.data = hashData;
-    hashDataBuf.length = 36;
-    
-    if ((err = CloneHashState(SSLHashSHA1, ctx->shaState, shaMsgState, ctx)) != 0)
-        goto fail;
-    if ((err = CloneHashState(SSLHashMD5, ctx->md5State, md5MsgState, ctx)) != 0)
-        goto fail;
-       assert(ctx->sslTslCalls != NULL);
-    if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx,        hashDataBuf, 
-                       shaMsgState, md5MsgState)) != 0)
-        goto fail;
-    
-       assert(ctx->signingPrivKeyRef != NULL);
-       err = SecKeyGetCSSMKey(ctx->signingPrivKeyRef, &cssmKey);
-       if(err) {
-               sslErrorLog("SSLEncodeCertificateVerify: SecKeyGetCSSMKey err %d\n", (int)err);
-               return err;
-       }
-       len = sslKeyLengthInBytes(cssmKey);
-    
-    certVerify.contentType = SSL_RecordTypeHandshake;
-       assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
-                  (ctx->negProtocolVersion == TLS_Version_1_0));
-    certVerify.protocolVersion = ctx->negProtocolVersion;
-    if ((err = SSLAllocBuffer(certVerify.contents, len + 6, ctx)) != 0)
-        goto fail;
-    
-    certVerify.contents.data[0] = SSL_HdskCertVerify;
-    SSLEncodeInt(certVerify.contents.data+1, len+2, 3);
-    SSLEncodeInt(certVerify.contents.data+4, len, 2);
-
-       err = sslRawSign(ctx,
-               ctx->signingPrivKeyRef,
-               hashData,                                               // data to sign 
-               36,                                                             // MD5 size + SHA1 size
-               certVerify.contents.data+6,             // signature destination
-               len,                                                    // we mallocd len+6
-               &outputLen);
-       if(err) {
-               goto fail;
-       }
-    
-    assert(outputLen == len);
-    
-    err = noErr;
-    
-fail:
-    SSLFreeBuffer(shaMsgState, ctx);
-    SSLFreeBuffer(md5MsgState, ctx);
-
-    return err;
-}
-
-OSStatus
-SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx)
-{   OSStatus        err;
-    UInt8           hashData[36];
-    UInt16          signatureLen;
-    SSLBuffer       hashDataBuf, shaMsgState, md5MsgState;
-    unsigned int    publicModulusLen;
-    
-    shaMsgState.data = 0;
-    md5MsgState.data = 0;
-    
-    if (message.length < 2) {
-       sslErrorLog("SSLProcessCertificateVerify: msg len error\n");
-        return errSSLProtocol;     
-    }
-    
-    signatureLen = (UInt16)SSLDecodeInt(message.data, 2);
-    if (message.length != (unsigned)(2 + signatureLen)) {
-       sslErrorLog("SSLProcessCertificateVerify: sig len error 1\n");
-        return errSSLProtocol;
-    }
-    
-       assert(ctx->peerPubKey != NULL);
-       publicModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
-    
-    if (signatureLen != publicModulusLen) {
-       sslErrorLog("SSLProcessCertificateVerify: sig len error 2\n");
-        return errSSLProtocol;
-    }
-    hashDataBuf.data = hashData;
-    hashDataBuf.length = 36;
-    
-    if ((err = CloneHashState(SSLHashSHA1, ctx->shaState, shaMsgState, ctx)) != 0)
-        goto fail;
-    if ((err = CloneHashState(SSLHashMD5, ctx->md5State, md5MsgState, ctx)) != 0)
-        goto fail;
-       assert(ctx->sslTslCalls != NULL);
-    if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, hashDataBuf, 
-                       shaMsgState, md5MsgState)) != 0)
-        goto fail;
-    
-       /* 
-        * The CSP does the decrypt & compare for us in one shot
-        */
-       err = sslRawVerify(ctx,
-               ctx->peerPubKey,
-               ctx->peerPubKeyCsp,             // FIXME - maybe we just use cspHand?
-               hashData,                               // data to verify
-               36,
-               message.data + 2,               // signature
-               signatureLen);
-       if(err) {
-               SSLFatalSessionAlert(SSL_AlertDecryptError, ctx);
-               goto fail;
-       }
-    err = noErr;
-    
-fail:
-    SSLFreeBuffer(shaMsgState, ctx);
-    SSLFreeBuffer(md5MsgState, ctx);
-
-    return err;
-}