]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslalert.c
Security-30.1.tar.gz
[apple/security.git] / SecureTransport / sslalert.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 /* *********************************************************************
20 File: sslalert.c
21
22 SSLRef 3.0 Final -- 11/19/96
23
24 Copyright (c)1996 by Netscape Communications Corp.
25
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.
29
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/>.
33
34 *********************************************************************
35
36 File: sslalert.c Support for alert protocol in SSL 3
37
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.
41
42 ****************************************************************** */
43
44 #include "ssl.h"
45
46 #ifndef _SSLALERT_H_
47 #include "sslalert.h"
48 #endif
49
50 #ifndef _SSLALLOC_H_
51 #include "sslalloc.h"
52 #endif
53
54 #ifndef _SSLCTX_H_
55 #include "sslctx.h"
56 #endif
57
58 #ifndef _SSLSESS_H_
59 #include "sslsess.h"
60 #endif
61
62 #ifndef _SSL_DEBUG_H_
63 #include "sslDebug.h"
64 #endif
65
66 SSLErr
67 SSLProcessAlert(SSLRecord rec, SSLContext *ctx)
68 { SSLErr err = SSLNoErr;
69 AlertLevel level;
70 AlertDescription desc;
71 uint8 *progress;
72 uint32 remaining;
73
74 if (rec.contents.length % 2 != 0)
75 { ERR(err = SSLFatalSessionAlert(alert_illegal_parameter, ctx));
76 if (!err)
77 ERR(err = SSLProtocolErr);
78 return err;
79 }
80
81 progress = rec.contents.data;
82 remaining = rec.contents.length;
83 while (remaining > 0)
84 { level = (AlertLevel)*progress++;
85 desc = (AlertDescription)*progress++;
86 remaining -= 2;
87
88 /*
89 * APPLE_CDSA changes: ignore sessionID-related failures here;
90 * the important thing is the alert.
91 */
92 if (level == alert_fatal)
93 {
94 SSLDeleteSessionID(ctx);
95 dprintf1("***Fatal alert %d received", desc);
96 return SSLFatalAlert;
97 }
98
99 switch (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;
106 * die anyway
107 */
108 SSLDeleteSessionID(ctx);
109 err = SSLFatalAlert;
110 break;
111 case alert_close_notify:
112 ERR(SSLClose(ctx));
113 err = SSLNoErr;
114 break;
115 case alert_no_certificate:
116 if (ctx->state == HandshakeClientCertificate)
117 if (ERR(err = SSLAdvanceHandshake(SSL_certificate, ctx)) != 0)
118 return err;
119 break;
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:
125 err = SSLNoErr;
126 break;
127 default:
128 /* Unknown alert, but not fatal; ignore it */
129 break;
130 }
131 }
132
133 return err;
134 }
135
136 SSLErr
137 SSLSendAlert(AlertLevel level, AlertDescription desc, SSLContext *ctx)
138 { SSLRecord rec;
139 SSLErr err;
140
141 CASSERT((ctx->negProtocolVersion == SSL_Version_3_0) ||
142 (ctx->negProtocolVersion == SSL_Version_Undetermined) ||
143 (ctx->negProtocolVersion == SSL_Version_3_0_Only));
144
145 if ((err = SSLEncodeAlert(&rec, level, desc, ctx)) != 0)
146 return err;
147 if ((err = SSLWriteRecord(rec, ctx)) != 0)
148 return err;
149 if ((err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx)) != 0)
150 return err;
151
152 return SSLNoErr;
153 }
154
155 SSLErr
156 SSLEncodeAlert(SSLRecord *rec, AlertLevel level, AlertDescription desc, SSLContext *ctx)
157 { SSLErr err;
158
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)
163 return err;
164 rec->contents.data[0] = level;
165 rec->contents.data[1] = desc;
166
167 return SSLNoErr;
168 }
169
170 SSLErr
171 SSLFatalSessionAlert(AlertDescription desc, SSLContext *ctx)
172 { SSLErr err1, err2;
173
174 if(desc != alert_close_notify) {
175 errorLog1("SSLFatalSessionAlert: desc %d\n", desc);
176 }
177 //dprintf0("SSLFatalSessionAlert: going to state ErrorClose\n");
178 SSLChangeHdskState(ctx, SSLErrorClose);
179
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);
183
184 /* Second, send the alert */
185 err2 = SSLSendAlert(alert_fatal, desc, ctx);
186
187 /* If they both returned errors, arbitrarily return the first */
188 return err1 != 0 ? err1 : err2;
189 }