/ lib / sslAlertMessage.c
sslAlertMessage.c
  1  /*
  2   * Copyright (c) 2000-2001,2005-2007,2010-2012 Apple Inc. All Rights Reserved.
  3   *
  4   * @APPLE_LICENSE_HEADER_START@
  5   *
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. Please obtain a copy of the License at
 10   * http://www.opensource.apple.com/apsl/ and read it before using this
 11   * file.
 12   *
 13   * The Original Code and all software distributed under the License are
 14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 18   * Please see the License for the specific language governing rights and
 19   * limitations under the License.
 20   *
 21   * @APPLE_LICENSE_HEADER_END@
 22   */
 23  
 24  /*
 25   * sslAlertMessage.c - SSL3 Alert protocol
 26   */
 27  
 28  #include "tls_handshake_priv.h"
 29  #include "sslAlertMessage.h"
 30  #include "sslHandshake.h"
 31  #include "sslHandshake_priv.h"
 32  #include "sslMemory.h"
 33  #include "sslSession.h"
 34  #include "sslDebug.h"
 35  #include "sslUtils.h"
 36  
 37  #include <assert.h>
 38  
 39  #if !SSL_DEBUG
 40  #define SSLLogAlertMsg(msg,sent)
 41  #else
 42  static void SSLLogAlertMsg(AlertDescription msg, bool sent);
 43  #endif
 44  
 45  static int SSLEncodeAlert(
 46  	tls_buffer *rec,
 47  	AlertLevel level,
 48  	AlertDescription desc,
 49  	tls_handshake_t ctx);
 50  
 51  /*
 52   * If a peer sends us any kind of a bad cert alert, we may need to adjust
 53   * ctx->clientCertState accordingly.
 54   */
 55  static void
 56  SSLDetectCertRejected(
 57  	tls_handshake_t ctx,
 58  	AlertDescription	desc)
 59  {
 60  	if(ctx->isServer) {
 61  		return;
 62  	}
 63  	if(ctx->clientCertState != kSSLClientCertSent) {
 64  		return;
 65  	}
 66  	switch(desc) {
 67  		case SSL_AlertBadCert:
 68  		case SSL_AlertUnsupportedCert:
 69  		case SSL_AlertCertRevoked:
 70  		case SSL_AlertCertExpired:
 71  		case SSL_AlertCertUnknown:
 72  		case SSL_AlertUnknownCA:
 73  			ctx->clientCertState = kSSLClientCertRejected;
 74  			break;
 75  		default:
 76  			break;
 77  	}
 78  }
 79  
 80  int
 81  SSLProcessAlert(tls_buffer rec, tls_handshake_t ctx)
 82  {   int            err = errSSLSuccess;
 83      AlertLevel          level;
 84      AlertDescription    desc;
 85      uint8_t             *charPtr;
 86      size_t              remaining;
 87  
 88      if (rec.length % 2 != 0)
 89      {
 90  		err = SSLFatalSessionAlert(SSL_AlertIllegalParam, ctx);
 91          if (!err) {
 92              err = errSSLProtocol;
 93  		}
 94          return err;
 95      }
 96  
 97      charPtr = rec.data;
 98      remaining = rec.length;
 99  	bool fatal = false;
100  
101      while (remaining > 0)
102      {   level = (AlertLevel)*charPtr++;
103          desc = (AlertDescription)*charPtr++;
104  		sslHdskMsgDebug("alert msg received level %d   desc %d",
105  			(int)level, (int)desc);
106          remaining -= 2;
107          SSLLogAlertMsg(desc, false);
108  
109          if (level == SSL_AlertLevelFatal) {
110  			/* explicit fatal errror */
111  			fatal = true;
112              sslErrorLog("***Fatal alert %d received\n", desc);
113          }
114          SSLDetectCertRejected(ctx, desc);
115  
116          switch (desc) {
117  			/* A number of these are fatal by implication */
118              case SSL_AlertUnexpectedMsg:
119  				err = errSSLPeerUnexpectedMsg;
120  				fatal = true;
121  				break;
122              case SSL_AlertBadRecordMac:
123   				err = errSSLPeerBadRecordMac;
124  				fatal = true;
125  				break;
126  			case SSL_AlertDecryptionFail_RESERVED:
127   				err = errSSLPeerDecryptionFail;
128  				fatal = true;
129  				break;
130              case SSL_AlertRecordOverflow:
131   				err = errSSLPeerRecordOverflow;
132  				fatal = true;
133  				break;
134              case SSL_AlertDecompressFail:
135   				err = errSSLPeerDecompressFail;
136  				fatal = true;
137  				break;
138              case SSL_AlertHandshakeFail:
139   				err = errSSLPeerHandshakeFail;
140  				fatal = true;
141  				break;
142              case SSL_AlertIllegalParam:
143   				err = errSSLIllegalParam;
144  				fatal = true;
145  				break;
146              case SSL_AlertBadCert:
147  				err = errSSLPeerBadCert;
148  				break;
149              case SSL_AlertUnsupportedCert:
150  				err = errSSLPeerUnsupportedCert;
151  				break;
152              case SSL_AlertCertRevoked:
153  				err = errSSLPeerCertRevoked;
154  				break;
155              case SSL_AlertCertExpired:
156  				err = errSSLPeerCertExpired;
157  				break;
158              case SSL_AlertCertUnknown:
159                  err = errSSLPeerCertUnknown;
160                  break;
161              case SSL_AlertUnknownCA:
162                  err = errSSLPeerUnknownCA;
163                  break;
164              case SSL_AlertAccessDenied:
165                  err = errSSLPeerAccessDenied;
166                  break;
167              case SSL_AlertDecodeError:
168                  err = errSSLPeerDecodeError;
169                  break;
170              case SSL_AlertDecryptError:
171                  err = errSSLPeerDecryptError;
172                  break;
173              case SSL_AlertExportRestriction_RESERVED:
174                  err = errSSLPeerExportRestriction;
175                  break;
176              case SSL_AlertProtocolVersion:
177                  err = errSSLPeerProtocolVersion;
178                  break;
179              case SSL_AlertInsufficientSecurity:
180                  err = errSSLPeerInsufficientSecurity;
181                  break;
182              case SSL_AlertInternalError:
183                  err = errSSLPeerInternalError;
184                  break;
185              case SSL_AlertUserCancelled:
186                  err = errSSLPeerUserCancelled;
187                  break;
188              case SSL_AlertNoRenegotiation:
189                  err = errSSLPeerNoRenegotiation;
190                  break;
191  			/* unusual cases.... */
192              case SSL_AlertCloseNotify:
193  				/* the clean "we're done" case */
194                  tls_handshake_close(ctx);
195                  err = errSSLClosedGraceful;
196                  break;
197              case SSL_AlertNoCert_RESERVED:
198                  if((ctx->state == SSL_HdskStateClientCert) &&
199  				   (ctx->isServer)) {
200  					/*
201  					 * Advance to
202  					 * state ClientKeyExchange by pretending we
203  					 * just got an empty client cert msg.
204  					 */
205                      if ((err = SSLAdvanceHandshake(SSL_HdskCert,
206  							ctx)) != 0) {
207                          return err;
208  					}
209  				}
210                  break;
211              case SSL_AlertUnsupportedExtension:
212                  err = errSSLFatalAlert;
213                  fatal = true;
214                  break;
215  
216              default:
217                  /* Unknown alert, ignore if not fatal */
218  				if(level == SSL_AlertLevelFatal) {
219  					err = errSSLFatalAlert;
220  				}
221  				else {
222  					err = errSSLSuccess;
223  				}
224                  break;
225          }
226  		if(fatal) {
227  			/* don't bother processing any more */
228  			break;
229  		}
230      }
231      if(fatal) {
232         	SSLDeleteSessionData(ctx);
233  	}
234      return err;
235  }
236  
237  int
238  SSLSendAlert(AlertLevel level, AlertDescription desc, tls_handshake_t ctx)
239  {
240      tls_buffer  rec;
241      int        err;
242  
243  	switch(ctx->negProtocolVersion) {
244  		case tls_protocol_version_Undertermined:
245  			/* Too early in negotiation to send an alert */
246  			return errSSLSuccess;
247  		default:
248  			break;
249  	}
250  	if(ctx->sentFatalAlert) {
251  		/* no more alerts allowed */
252  		return errSSLSuccess;
253  	}
254      if ((err = SSLEncodeAlert(&rec, level, desc, ctx)) != 0)
255          return err;
256  	SSLLogAlertMsg(desc, true);
257      err = ctx->callbacks->write(ctx->callback_ctx, rec, tls_record_type_Alert);
258      SSLFreeBuffer(&rec);
259      if(desc == SSL_AlertCloseNotify) {
260  		/* no more alerts allowed */
261  		ctx->sentFatalAlert = true;
262  	}
263      return err;
264  }
265  
266  static int
267  SSLEncodeAlert(tls_buffer *rec, AlertLevel level, AlertDescription desc, tls_handshake_t ctx)
268  {   int          err;
269  
270      rec->length = 2;
271      if ((err = SSLAllocBuffer(rec, 2)))
272          return err;
273      rec->data[0] = level;
274      rec->data[1] = desc;
275  
276      return errSSLSuccess;
277  }
278  
279  int
280  SSLFatalSessionAlert(AlertDescription desc, tls_handshake_t ctx)
281  {   int          err1, err2;
282  
283      if(desc != SSL_AlertCloseNotify) {
284      	sslHdskMsgDebug("SSLFatalSessionAlert: desc %d\n", desc);
285      }
286      SSLChangeHdskState(ctx, SSL_HdskStateErrorClose);
287  
288  	if(ctx->negProtocolVersion < tls_protocol_version_TLS_1_0) {
289  		/* translate to SSL3 if necessary */
290  		switch(desc) {
291  			//case SSL_AlertDecryptionFail_RESERVED:
292  			case SSL_AlertRecordOverflow:
293  			case SSL_AlertAccessDenied:
294  			case SSL_AlertDecodeError:
295  			case SSL_AlertDecryptError:
296  			//case SSL_AlertExportRestriction_RESERVED:
297  			case SSL_AlertProtocolVersion:
298  			case SSL_AlertInsufficientSecurity:
299  			case SSL_AlertUserCancelled:
300  			case SSL_AlertNoRenegotiation:
301  				desc = SSL_AlertHandshakeFail;
302  				break;
303  			case SSL_AlertUnknownCA:
304  				desc = SSL_AlertUnsupportedCert;
305  				break;
306  			case SSL_AlertInternalError:
307  				desc = SSL_AlertCloseNotify;
308  				break;
309  			default:
310  				/* send as is */
311  				break;
312  		}
313  	}
314      /* Make session unresumable; I'm not stopping if I get an error,
315          because I'd like to attempt to send the alert anyway */
316      err1 = SSLDeleteSessionData(ctx);
317  
318      /* Second, send the alert */
319      err2 = SSLSendAlert(SSL_AlertLevelFatal, desc, ctx);
320  
321  	ctx->sentFatalAlert = true;
322  
323      /* If they both returned errors, arbitrarily return the first */
324      return err1 != 0 ? err1 : err2;
325  }
326  
327  #if SSL_DEBUG
328  
329  /* log alert messages */
330  static char *alertMsgToStr(AlertDescription msg)
331  {
332  	static char badStr[100];
333  
334  	switch(msg) {
335  		case SSL_AlertCloseNotify:
336  			return "SSL_AlertCloseNotify";
337  		case SSL_AlertUnexpectedMsg:
338  			return "SSL_AlertUnexpectedMsg";
339  		case SSL_AlertBadRecordMac:
340  			return "SSL_AlertBadRecordMac";
341  		case SSL_AlertDecryptionFail_RESERVED:
342  			return "SSL_AlertDecryptionFail";
343  		case SSL_AlertRecordOverflow:
344  			return "SSL_AlertRecordOverflow";
345  		case SSL_AlertDecompressFail:
346  			return "SSL_AlertDecompressFail";
347  		case SSL_AlertHandshakeFail:
348  			return "SSL_AlertHandshakeFail";
349  		case SSL_AlertNoCert_RESERVED:
350  			return "SSL_AlertNoCert";
351  		case SSL_AlertBadCert:
352  			return "SSL_AlertBadCert";
353  		case SSL_AlertUnsupportedCert:
354  			return "SSL_AlertUnsupportedCert";
355  		case SSL_AlertCertRevoked:
356  			return "SSL_AlertCertRevoked";
357  
358  		case SSL_AlertCertExpired:
359  			return "SSL_AlertCertExpired";
360  		case SSL_AlertCertUnknown:
361  			return "SSL_AlertCertUnknown";
362  		case SSL_AlertIllegalParam:
363  			return "SSL_AlertIllegalParam";
364  		case SSL_AlertUnknownCA:
365  			return "SSL_AlertUnknownCA";
366  		case SSL_AlertAccessDenied:
367  			return "SSL_AlertAccessDenied";
368  		case SSL_AlertDecodeError:
369  			return "SSL_AlertDecodeError";
370  		case SSL_AlertDecryptError:
371  			return "SSL_AlertDecryptError";
372  
373  		case SSL_AlertExportRestriction_RESERVED:
374  			return "SSL_AlertExportRestriction";
375  		case SSL_AlertProtocolVersion:
376  			return "SSL_AlertProtocolVersion";
377  		case SSL_AlertInsufficientSecurity:
378  			return "SSL_AlertInsufficientSecurity";
379  		case SSL_AlertInternalError:
380  			return "SSL_AlertInternalError";
381  		case SSL_AlertUserCancelled:
382  			return "SSL_AlertUserCancelled";
383  		case SSL_AlertNoRenegotiation:
384  			return "SSL_AlertNoRenegotiation";
385  
386  		default:
387  			sprintf(badStr, "Unknown state (%d)", msg);
388  			return badStr;
389  	}
390  }
391  
392  static void SSLLogAlertMsg(AlertDescription msg, bool sent)
393  {
394  	sslHdskMsgDebug("---%s alert msg %s",
395  		alertMsgToStr(msg), (sent ? "sent" : "recv"));
396  }
397  
398  #endif	/* SSL_DEBUG */