int tls_handshake_continue(tls_handshake_t filter) { int err; if(!filter->advanceHandshake) return 0; require_noerr((err=SSLAdvanceHandshake(filter->currentMessage, filter)), errOut); if (filter->fragmentedMessageCache.data != 0) err = SSLProcessHandshakeRecordInner(filter->fragmentedMessageCache, filter); errOut: return err; }
/* (re)handshake */ int tls_handshake_negotiate(tls_handshake_t filter, tls_buffer *peerID) { assert(!filter->isServer); if ((filter->state != SSL_HdskStateClientReady) && (filter->state != SSL_HdskStateClientUninit)) { sslDebugLog("Requesting renegotiation while handshake in progress..."); return errSSLIllegalParam; // TODO: better error code for this case. } if(peerID) { check(filter->peerID.data==NULL); // Note sure that's illegal, but it's fishy filter->callbacks->load_session_data(filter->callback_ctx, *peerID, &filter->resumableSession); SSLFreeBuffer(&filter->peerID); SSLCopyBuffer(peerID, &filter->peerID); } else { SSLFreeBuffer(&filter->peerID); } return SSLAdvanceHandshake(SSL_HdskHelloRequest, filter); }
OSStatus SSLProcessAlert(SSLRecord rec, SSLContext *ctx) { OSStatus err = errSecSuccess; AlertLevel level; AlertDescription desc; uint8_t *charPtr; size_t remaining; if (rec.contents.length % 2 != 0) { err = SSLFatalSessionAlert(SSL_AlertIllegalParam, ctx); if (!err) { err = errSSLProtocol; } return err; } charPtr = rec.contents.data; remaining = rec.contents.length; bool fatal = false; while (remaining > 0) { level = (AlertLevel)*charPtr++; desc = (AlertDescription)*charPtr++; sslHdskMsgDebug("alert msg received level %d desc %d", (int)level, (int)desc); remaining -= 2; SSLLogAlertMsg(desc, false); if (level == SSL_AlertLevelFatal) { /* explicit fatal errror */ fatal = true; sslErrorLog("***Fatal alert %d received\n", desc); } SSLDetectCertRejected(ctx, desc); switch (desc) { /* A number of these are fatal by implication */ case SSL_AlertUnexpectedMsg: err = errSSLPeerUnexpectedMsg; fatal = true; break; case SSL_AlertBadRecordMac: err = errSSLPeerBadRecordMac; fatal = true; break; case SSL_AlertDecryptionFail_RESERVED: err = errSSLPeerDecryptionFail; fatal = true; break; case SSL_AlertRecordOverflow: err = errSSLPeerRecordOverflow; fatal = true; break; case SSL_AlertDecompressFail: err = errSSLPeerDecompressFail; fatal = true; break; case SSL_AlertHandshakeFail: err = errSSLPeerHandshakeFail; fatal = true; break; case SSL_AlertIllegalParam: err = errSSLIllegalParam; fatal = true; break; case SSL_AlertBadCert: err = errSSLPeerBadCert; break; case SSL_AlertUnsupportedCert: err = errSSLPeerUnsupportedCert; break; case SSL_AlertCertRevoked: err = errSSLPeerCertRevoked; break; case SSL_AlertCertExpired: err = errSSLPeerCertExpired; break; case SSL_AlertCertUnknown: err = errSSLPeerCertUnknown; break; case SSL_AlertUnknownCA: err = errSSLPeerUnknownCA; break; case SSL_AlertAccessDenied: err = errSSLPeerAccessDenied; break; case SSL_AlertDecodeError: err = errSSLPeerDecodeError; break; case SSL_AlertDecryptError: err = errSSLPeerDecryptError; break; case SSL_AlertExportRestriction_RESERVED: err = errSSLPeerExportRestriction; break; case SSL_AlertProtocolVersion: err = errSSLPeerProtocolVersion; break; case SSL_AlertInsufficientSecurity: err = errSSLPeerInsufficientSecurity; break; case SSL_AlertInternalError: err = errSSLPeerInternalError; break; case SSL_AlertUserCancelled: err = errSSLPeerUserCancelled; break; case SSL_AlertNoRenegotiation: err = errSSLPeerNoRenegotiation; break; /* unusual cases.... */ case SSL_AlertCloseNotify: /* the clean "we're done" case */ SSLClose(ctx); err = errSecSuccess; break; case SSL_AlertNoCert_RESERVED: if((ctx->state == SSL_HdskStateClientCert) && (ctx->protocolSide == kSSLServerSide) && (ctx->clientAuth != kAlwaysAuthenticate)) { /* * Tolerate this unless we're configured to * *require* a client cert. If a client cert is * required, we'll catch the error at the next * handshake msg we receive - which will probably * be a client key exchange msg, which is illegal * when we're in state SSL_HdskStateClientCert. * If the client cert is optional, advance to * state ClientKeyExchange by pretending we * just got a client cert msg. */ if ((err = SSLAdvanceHandshake(SSL_HdskCert, ctx)) != 0) { return err; } } break; case SSL_AlertUnsupportedExtension: err = errSSLFatalAlert; fatal = true; break; default: /* Unknown alert, ignore if not fatal */ if(level == SSL_AlertLevelFatal) { err = errSSLFatalAlert; } else { err = errSecSuccess; } break; } if(fatal) { /* don't bother processing any more */ break; } } if(fatal) { SSLDeleteSessionData(ctx); } return err; }