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 ****************************************************************** */
67 SSLProcessAlert(SSLRecord rec
, SSLContext
*ctx
)
68 { SSLErr err
= SSLNoErr
;
70 AlertDescription desc
;
74 if (rec
.contents
.length
% 2 != 0)
75 { ERR(err
= SSLFatalSessionAlert(alert_illegal_parameter
, ctx
));
77 ERR(err
= SSLProtocolErr
);
81 progress
= rec
.contents
.data
;
82 remaining
= rec
.contents
.length
;
84 { level
= (AlertLevel
)*progress
++;
85 desc
= (AlertDescription
)*progress
++;
89 * APPLE_CDSA changes: ignore sessionID-related failures here;
90 * the important thing is the alert.
92 if (level
== alert_fatal
)
94 SSLDeleteSessionID(ctx
);
95 dprintf1("***Fatal alert %d received", desc
);
100 { case alert_unexpected_message
:
101 case alert_bad_record_mac
:
102 case alert_decompression_failure
:
103 case alert_handshake_failure
:
104 case alert_illegal_parameter
:
105 /* These must always be fatal; if we got here, the level is warning;
108 SSLDeleteSessionID(ctx
);
111 case alert_close_notify
:
115 case alert_no_certificate
:
116 if (ctx
->state
== HandshakeClientCertificate
)
117 if (ERR(err
= SSLAdvanceHandshake(SSL_certificate
, ctx
)) != 0)
120 case alert_bad_certificate
:
121 case alert_unsupported_certificate
:
122 case alert_certificate_revoked
:
123 case alert_certificate_expired
:
124 case alert_certificate_unknown
:
128 /* Unknown alert, but not fatal; ignore it */
137 SSLSendAlert(AlertLevel level
, AlertDescription desc
, SSLContext
*ctx
)
141 CASSERT((ctx
->negProtocolVersion
== SSL_Version_3_0
) ||
142 (ctx
->negProtocolVersion
== SSL_Version_Undetermined
) ||
143 (ctx
->negProtocolVersion
== SSL_Version_3_0_Only
));
145 if ((err
= SSLEncodeAlert(&rec
, level
, desc
, ctx
)) != 0)
147 if ((err
= SSLWriteRecord(rec
, ctx
)) != 0)
149 if ((err
= SSLFreeBuffer(&rec
.contents
, &ctx
->sysCtx
)) != 0)
156 SSLEncodeAlert(SSLRecord
*rec
, AlertLevel level
, AlertDescription desc
, SSLContext
*ctx
)
159 rec
->contentType
= SSL_alert
;
160 rec
->protocolVersion
= SSL_Version_3_0
;
161 rec
->contents
.length
= 2;
162 if ((err
= SSLAllocBuffer(&rec
->contents
, 2, &ctx
->sysCtx
)) != 0)
164 rec
->contents
.data
[0] = level
;
165 rec
->contents
.data
[1] = desc
;
171 SSLFatalSessionAlert(AlertDescription desc
, SSLContext
*ctx
)
174 if(desc
!= alert_close_notify
) {
175 errorLog1("SSLFatalSessionAlert: desc %d\n", desc
);
177 //dprintf0("SSLFatalSessionAlert: going to state ErrorClose\n");
178 SSLChangeHdskState(ctx
, SSLErrorClose
);
180 /* Make session unresumable; I'm not stopping if I get an error,
181 because I'd like to attempt to send the alert anyway */
182 err1
= SSLDeleteSessionID(ctx
);
184 /* Second, send the alert */
185 err2
= SSLSendAlert(alert_fatal
, desc
, ctx
);
187 /* If they both returned errors, arbitrarily return the first */
188 return err1
!= 0 ? err1
: err2
;