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 /* *********************************************************************
20 File: sslAlertMessage.cpp - SSL3 Alert protocol
21 ****************************************************************** */
24 #include "sslAlertMessage.h"
25 #include "sslMemory.h"
26 #include "sslContext.h"
27 #include "sslSession.h"
33 #define SSLLogAlertMsg(msg,sent)
35 static void SSLLogAlertMsg(AlertDescription msg
, bool sent
);
39 SSLProcessAlert(SSLRecord rec
, SSLContext
*ctx
)
40 { OSStatus err
= noErr
;
42 AlertDescription desc
;
46 if (rec
.contents
.length
% 2 != 0)
48 err
= SSLFatalSessionAlert(SSL_AlertIllegalParam
, ctx
);
55 charPtr
= rec
.contents
.data
;
56 remaining
= rec
.contents
.length
;
58 { level
= (AlertLevel
)*charPtr
++;
59 desc
= (AlertDescription
)*charPtr
++;
60 sslHdskMsgDebug("alert msg recieved level %d desc %d\n",
61 (int)level
, (int)desc
);
63 SSLLogAlertMsg(desc
, false);
66 * Ignore sessionID-related failures here;
67 * the important thing is the alert.
69 if (level
== SSL_AlertLevelFatal
)
71 SSLDeleteSessionData(ctx
);
72 sslErrorLog("***Fatal alert %d received\n", desc
);
73 return errSSLFatalAlert
;
77 { case SSL_AlertUnexpectedMsg
:
78 case SSL_AlertBadRecordMac
:
79 case SSL_AlertDecompressFail
:
80 case SSL_AlertHandshakeFail
:
81 case SSL_AlertIllegalParam
:
82 /* These must always be fatal; if we got here, the level is warning;
85 SSLDeleteSessionData(ctx
);
86 err
= errSSLFatalAlert
;
88 case SSL_AlertCloseNotify
:
93 if((ctx
->state
== SSL_HdskStateClientCert
) &&
94 (ctx
->protocolSide
== SSL_ServerSide
) &&
95 (ctx
->clientAuth
!= kAlwaysAuthenticate
)) {
97 * Tolerate this unless we're configured to
98 * *require* a client cert. If a client cert is
99 * required, we'll catch the error at the next
100 * handshake msg we receive - which will probably
101 * be a client key exchange msg, which is illegal
102 * when we're in state SSL_HdskStateClientCert.
103 * If the client cert is optional, advance to
104 * state ClientKeyExchange by pretending we
105 * just got a client cert msg.
107 if ((err
= SSLAdvanceHandshake(SSL_HdskCert
,
113 case SSL_AlertBadCert
:
114 case SSL_AlertUnsupportedCert
:
115 case SSL_AlertCertRevoked
:
116 case SSL_AlertCertExpired
:
117 case SSL_AlertCertUnknown
:
121 /* Unknown alert, but not fatal; ignore it */
130 SSLSendAlert(AlertLevel level
, AlertDescription desc
, SSLContext
*ctx
)
134 assert((ctx
->negProtocolVersion
!= SSL_Version_2_0
));
136 if ((err
= SSLEncodeAlert(rec
, level
, desc
, ctx
)) != 0)
138 assert(ctx
->sslTslCalls
!= NULL
);
139 SSLLogAlertMsg(desc
, true);
140 if ((err
= ctx
->sslTslCalls
->writeRecord(rec
, ctx
)) != 0)
142 if ((err
= SSLFreeBuffer(rec
.contents
, ctx
)) != 0)
149 SSLEncodeAlert(SSLRecord
&rec
, AlertLevel level
, AlertDescription desc
, SSLContext
*ctx
)
152 rec
.contentType
= SSL_RecordTypeAlert
;
153 assert((ctx
->negProtocolVersion
!= SSL_Version_2_0
));
154 if(ctx
->negProtocolVersion
== SSL_Version_Undetermined
) {
155 /* error while negotiating */
156 rec
.protocolVersion
= ctx
->maxProtocolVersion
;
159 rec
.protocolVersion
= ctx
->negProtocolVersion
;
161 rec
.contents
.length
= 2;
162 if ((err
= SSLAllocBuffer(rec
.contents
, 2, ctx
)) != 0)
164 rec
.contents
.data
[0] = level
;
165 rec
.contents
.data
[1] = desc
;
171 SSLFatalSessionAlert(AlertDescription desc
, SSLContext
*ctx
)
172 { OSStatus err1
, err2
;
174 if(desc
!= SSL_AlertCloseNotify
) {
175 sslErrorLog("SSLFatalSessionAlert: desc %d\n", desc
);
177 SSLChangeHdskState(ctx
, SSL_HdskStateErrorClose
);
179 /* Make session unresumable; I'm not stopping if I get an error,
180 because I'd like to attempt to send the alert anyway */
181 err1
= SSLDeleteSessionData(ctx
);
183 /* Second, send the alert */
184 err2
= SSLSendAlert(SSL_AlertLevelFatal
, desc
, ctx
);
186 /* If they both returned errors, arbitrarily return the first */
187 return err1
!= 0 ? err1
: err2
;
192 /* log alert messages */
194 static char *alertMsgToStr(AlertDescription msg
)
196 static char badStr
[100];
199 case SSL_AlertCloseNotify
:
200 return "SSL_AlertCloseNotify";
201 case SSL_AlertUnexpectedMsg
:
202 return "SSL_AlertUnexpectedMsg";
203 case SSL_AlertBadRecordMac
:
204 return "SSL_AlertBadRecordMac";
205 case SSL_AlertDecryptionFail
:
206 return "SSL_AlertDecryptionFail";
207 case SSL_AlertRecordOverflow
:
208 return "SSL_AlertRecordOverflow";
209 case SSL_AlertDecompressFail
:
210 return "SSL_AlertDecompressFail";
211 case SSL_AlertHandshakeFail
:
212 return "SSL_AlertHandshakeFail";
213 case SSL_AlertNoCert
:
214 return "SSL_AlertNoCert";
215 case SSL_AlertBadCert
:
216 return "SSL_AlertBadCert";
217 case SSL_AlertUnsupportedCert
:
218 return "SSL_AlertUnsupportedCert";
219 case SSL_AlertCertRevoked
:
220 return "SSL_AlertCertRevoked";
222 case SSL_AlertCertExpired
:
223 return "SSL_AlertCertExpired";
224 case SSL_AlertCertUnknown
:
225 return "SSL_AlertCertUnknown";
226 case SSL_AlertIllegalParam
:
227 return "SSL_AlertIllegalParam";
228 case SSL_AlertUnknownCA
:
229 return "SSL_AlertUnknownCA";
230 case SSL_AlertAccessDenied
:
231 return "SSL_AlertAccessDenied";
232 case SSL_AlertDecodeError
:
233 return "SSL_AlertDecodeError";
234 case SSL_AlertDecryptError
:
235 return "SSL_AlertDecryptError";
237 case SSL_AlertExportRestriction
:
238 return "SSL_AlertExportRestriction";
239 case SSL_AlertProtocolVersion
:
240 return "SSL_AlertProtocolVersion";
241 case SSL_AlertInsufficientSecurity
:
242 return "SSL_AlertInsufficientSecurity";
243 case SSL_AlertInternalError
:
244 return "SSL_AlertInternalError";
245 case SSL_AlertUserCancelled
:
246 return "SSL_AlertUserCancelled";
247 case SSL_AlertNoRenegotiation
:
248 return "SSL_AlertNoRenegotiation";
251 sprintf(badStr
, "Unknown state (%d(d)", msg
);
256 static void SSLLogAlertMsg(AlertDescription msg
, bool sent
)
258 sslHdskMsgDebug("---%s alert msg %s",
259 alertMsgToStr(msg
), (sent
? "sent" : "recv"));