2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
19 /* *********************************************************************
22 SSLRef 3.0 Final -- 11/19/96
24 Copyright (c)1996 by Netscape Communications Corp.
26 By retrieving this software you are bound by the licensing terms
27 disclosed in the file "LICENSE.txt". Please read it, and if you don't
28 accept the terms, delete this software.
30 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
31 View, California <http://home.netscape.com/> and Consensus Development
32 Corporation of Berkeley, California <http://www.consensus.com/>.
34 *********************************************************************
36 File: sslalert.c Support for alert protocol in SSL 3
38 Encoding, decoding and processing for the SSL alert protocol. Also,
39 support for sending fatal alerts, which also closes down our
40 connection, including invalidating our cached session.
42 ****************************************************************** */
69 SSLProcessAlert(SSLRecord rec
, SSLContext
*ctx
)
70 { SSLErr err
= SSLNoErr
;
72 AlertDescription desc
;
76 if (rec
.contents
.length
% 2 != 0)
77 { ERR(err
= SSLFatalSessionAlert(alert_illegal_parameter
, ctx
));
79 ERR(err
= SSLProtocolErr
);
83 progress
= rec
.contents
.data
;
84 remaining
= rec
.contents
.length
;
86 { level
= (AlertLevel
)*progress
++;
87 desc
= (AlertDescription
)*progress
++;
91 * APPLE_CDSA changes: ignore sessionID-related failures here;
92 * the important thing is the alert.
94 if (level
== alert_fatal
)
96 SSLDeleteSessionData(ctx
);
97 dprintf1("***Fatal alert %d received", desc
);
102 { case alert_unexpected_message
:
103 case alert_bad_record_mac
:
104 case alert_decompression_failure
:
105 case alert_handshake_failure
:
106 case alert_illegal_parameter
:
107 /* These must always be fatal; if we got here, the level is warning;
110 SSLDeleteSessionData(ctx
);
113 case alert_close_notify
:
117 case alert_no_certificate
:
118 if (ctx
->state
== HandshakeClientCertificate
)
119 if (ERR(err
= SSLAdvanceHandshake(SSL_certificate
, ctx
)) != 0)
122 case alert_bad_certificate
:
123 case alert_unsupported_certificate
:
124 case alert_certificate_revoked
:
125 case alert_certificate_expired
:
126 case alert_certificate_unknown
:
130 /* Unknown alert, but not fatal; ignore it */
139 SSLSendAlert(AlertLevel level
, AlertDescription desc
, SSLContext
*ctx
)
143 CASSERT((ctx
->negProtocolVersion
!= SSL_Version_2_0
));
145 if ((err
= SSLEncodeAlert(&rec
, level
, desc
, ctx
)) != 0)
147 assert(ctx
->sslTslCalls
!= NULL
);
148 if ((err
= ctx
->sslTslCalls
->writeRecord(rec
, ctx
)) != 0)
150 if ((err
= SSLFreeBuffer(&rec
.contents
, &ctx
->sysCtx
)) != 0)
157 SSLEncodeAlert(SSLRecord
*rec
, AlertLevel level
, AlertDescription desc
, SSLContext
*ctx
)
160 rec
->contentType
= SSL_alert
;
161 CASSERT((ctx
->negProtocolVersion
!= SSL_Version_2_0
));
162 if(ctx
->negProtocolVersion
== SSL_Version_Undetermined
) {
163 /* error while negotiating */
164 rec
->protocolVersion
= ctx
->maxProtocolVersion
;
167 rec
->protocolVersion
= ctx
->negProtocolVersion
;
169 rec
->contents
.length
= 2;
170 if ((err
= SSLAllocBuffer(&rec
->contents
, 2, &ctx
->sysCtx
)) != 0)
172 rec
->contents
.data
[0] = level
;
173 rec
->contents
.data
[1] = desc
;
179 SSLFatalSessionAlert(AlertDescription desc
, SSLContext
*ctx
)
182 if(desc
!= alert_close_notify
) {
183 errorLog1("SSLFatalSessionAlert: desc %d\n", desc
);
185 //dprintf0("SSLFatalSessionAlert: going to state ErrorClose\n");
186 SSLChangeHdskState(ctx
, SSLErrorClose
);
188 /* Make session unresumable; I'm not stopping if I get an error,
189 because I'd like to attempt to send the alert anyway */
190 err1
= SSLDeleteSessionData(ctx
);
192 /* Second, send the alert */
193 err2
= SSLSendAlert(alert_fatal
, desc
, ctx
);
195 /* If they both returned errors, arbitrarily return the first */
196 return err1
!= 0 ? err1
: err2
;