]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_ssl/lib/sslTransport.c
Security-58286.20.16.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / lib / sslTransport.c
index bc44005d61113e3fed3a128594f5a76773fce7b6..616b9d492eb371280b44fb70fced61b4a7dfad07 100644 (file)
@@ -60,6 +60,7 @@ extern int kSplitDefaultValue;
 
 static OSStatus SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx);
 static OSStatus SSLHandshakeProceed(SSLContext *ctx);
 
 static OSStatus SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx);
 static OSStatus SSLHandshakeProceed(SSLContext *ctx);
+static OSStatus SSLSendAlert(SSLContext *ctx, tls_alert_level_t level, tls_alert_t description);
 
 OSStatus 
 SSLWrite(
 
 OSStatus 
 SSLWrite(
@@ -84,6 +85,7 @@ SSLWrite(
                err = errSSLClosedGraceful;
                        goto abort;
         case SSL_HdskStateErrorClose:
                err = errSSLClosedGraceful;
                        goto abort;
         case SSL_HdskStateErrorClose:
+        case SSL_HdskStateOutOfBandError:
                err = errSSLClosedAbort;
                        goto abort;
            case SSL_HdskStateReady:
                err = errSSLClosedAbort;
                        goto abort;
            case SSL_HdskStateReady:
@@ -172,6 +174,7 @@ readRetry:
                        err = errSSLClosedGraceful;
                        goto abort;
                case SSL_HdskStateErrorClose:
                        err = errSSLClosedGraceful;
                        goto abort;
                case SSL_HdskStateErrorClose:
+        case SSL_HdskStateOutOfBandError:
                        err = errSSLClosedAbort;
                        goto abort;
                case SSL_HdskStateNoNotifyClose:
                        err = errSSLClosedAbort;
                        goto abort;
                case SSL_HdskStateNoNotifyClose:
@@ -374,12 +377,17 @@ SSLReHandshake(SSLContext *ctx)
         return errSecParam;
     }
 
         return errSecParam;
     }
 
-    if (ctx->state == SSL_HdskStateGracefulClose)
-        return errSSLClosedGraceful;
-    if (ctx->state == SSL_HdskStateErrorClose)
-        return errSSLClosedAbort;
-    if (ctx->state == SSL_HdskStatePending)
-        return errSecBadReq;
+    switch (ctx->state) {
+        case SSL_HdskStateGracefulClose:
+            return errSSLClosedGraceful;
+        case SSL_HdskStateErrorClose:
+        case SSL_HdskStateOutOfBandError:
+            return errSSLClosedAbort;
+        case SSL_HdskStatePending:
+            return errSecBadReq;
+        default:
+            break;
+    }
 
     /* If we are the client, we start the negotiation */
     if(ctx->protocolSide == kSSLClientSide) {
 
     /* If we are the client, we start the negotiation */
     if(ctx->protocolSide == kSSLClientSide) {
@@ -397,10 +405,15 @@ SSLHandshake(SSLContext *ctx)
        if(ctx == NULL) {
                return errSecParam;
        }
        if(ctx == NULL) {
                return errSecParam;
        }
-    if (ctx->state == SSL_HdskStateGracefulClose)
-        return errSSLClosedGraceful;
-    if (ctx->state == SSL_HdskStateErrorClose)
-        return errSSLClosedAbort;
+
+    switch (ctx->state) {
+        case SSL_HdskStateGracefulClose:
+            return errSSLClosedGraceful;
+        case SSL_HdskStateErrorClose:
+            return errSSLClosedAbort;
+        default:
+            break;
+    }
 
     if(ctx->isDTLS && ctx->timeout_deadline) {
         CFAbsoluteTime current = CFAbsoluteTimeGetCurrent();
 
     if(ctx->isDTLS && ctx->timeout_deadline) {
         CFAbsoluteTime current = CFAbsoluteTimeGetCurrent();
@@ -426,6 +439,27 @@ SSLHandshake(SSLContext *ctx)
         SSLChangeHdskState(ctx, SSL_HdskStatePending);
     }
 
         SSLChangeHdskState(ctx, SSL_HdskStatePending);
     }
 
+    /* If an out-of-band error occurred, handle it here and then terminate
+     the connection as needed. */
+    if (ctx->state == SSL_HdskStateOutOfBandError) {
+        bool shouldClose = true;
+        switch (ctx->outOfBandError) {
+            case errSecCertificateExpired:
+                SSLSendAlert(ctx, tls_handshake_alert_level_fatal, tls_handshake_alert_CertExpired);
+                break;
+            case errSecCertificateRevoked:
+                SSLSendAlert(ctx, tls_handshake_alert_level_fatal, tls_handshake_alert_CertRevoked);
+                break;
+            default:
+                shouldClose = false;
+                break;
+        }
+
+        if (shouldClose) {
+            return SSLClose(ctx);
+        }
+    }
+
     do {
         err = SSLHandshakeProceed(ctx);
         if((err != 0) && (err != errSSLUnexpectedRecord))
     do {
         err = SSLHandshakeProceed(ctx);
         if((err != 0) && (err != errSSLUnexpectedRecord))
@@ -545,11 +579,30 @@ SSLClose(SSLContext *ctx)
         err = SSLServiceWriteQueue(ctx);
 
     SSLChangeHdskState(ctx, SSL_HdskStateGracefulClose);
         err = SSLServiceWriteQueue(ctx);
 
     SSLChangeHdskState(ctx, SSL_HdskStateGracefulClose);
-    if (err == errSecIO)
+    if (err == errSecIO) 
         err = errSecSuccess;     /* Ignore errors related to closed streams */
     return err;
 }
 
         err = errSecSuccess;     /* Ignore errors related to closed streams */
     return err;
 }
 
+static OSStatus
+SSLSendAlert(SSLContext *ctx, tls_alert_level_t alertLevel, tls_alert_t alert)
+{
+    sslHdskStateDebug("SSLSendAlert");
+    if (ctx == NULL) {
+        return errSecParam;
+    }
+
+    return tls_handshake_send_alert(ctx->hdsk, alertLevel, alert);
+}
+
+OSStatus
+SSLSetError(SSLContext *ctx, OSStatus error)
+{
+    ctx->state = SSL_HdskStateOutOfBandError;
+    ctx->outOfBandError = error;
+    return errSecSuccess;
+}
+
 /*
  * Determine how much data the client can be guaranteed to
  * obtain via SSLRead() without blocking or causing any low-level
 /*
  * Determine how much data the client can be guaranteed to
  * obtain via SSLRead() without blocking or causing any low-level