Fix alert handling.
Fix OpenSSL 0.9.8 alert handling. PR#3038
This commit is contained in:

committed by
Dr. Stephen Henson

parent
d471adf351
commit
a375025e4d
6
CHANGES
6
CHANGES
@@ -4,6 +4,12 @@
|
||||
|
||||
Changes between 0.9.8y and 0.9.8za [xx XXX xxxx]
|
||||
|
||||
*) Fix handling of warning-level alerts in SSL23 client mode so they
|
||||
don't cause client-side termination (eg. on SNI unrecognized_name
|
||||
warnings). Add client and server support for six additional alerts
|
||||
per RFC 6066 and RFC 4279.
|
||||
[mancha]
|
||||
|
||||
*) Add option SSL_OP_SAFARI_ECDHE_ECDSA_BUG (part of SSL_OP_ALL) which
|
||||
avoids preferring ECDHE-ECDSA ciphers when the client appears to be
|
||||
Safari on OS X. Safari on OS X 10.8..10.8.3 advertises support for
|
||||
|
18
apps/s_cb.c
18
apps/s_cb.c
@@ -518,6 +518,24 @@ void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
|
||||
case 100:
|
||||
str_details2 = " no_renegotiation";
|
||||
break;
|
||||
case 110:
|
||||
str_details2 = " unsupported_extension";
|
||||
break;
|
||||
case 111:
|
||||
str_details2 = " certificate_unobtainable";
|
||||
break;
|
||||
case 112:
|
||||
str_details2 = " unrecognized_name";
|
||||
break;
|
||||
case 113:
|
||||
str_details2 = " bad_certificate_status_response";
|
||||
break;
|
||||
case 114:
|
||||
str_details2 = " bad_certificate_hash_value";
|
||||
break;
|
||||
case 115:
|
||||
str_details2 = " unknown_psk_identity";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -71,6 +71,11 @@ R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071
|
||||
R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080
|
||||
R SSL_R_TLSV1_ALERT_USER_CANCELLED 1090
|
||||
R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100
|
||||
R SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
|
||||
R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111
|
||||
R SSL_R_TLSV1_UNRECOGNIZED_NAME 1112
|
||||
R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113
|
||||
R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114
|
||||
|
||||
R RSAREF_R_CONTENT_ENCODING 0x0400
|
||||
R RSAREF_R_DATA 0x0401
|
||||
|
@@ -509,7 +509,7 @@ static int ssl23_get_server_hello(SSL *s)
|
||||
/* use special padding (SSL 3.0 draft/RFC 2246, App. E.2) */
|
||||
s->s2->ssl2_rollback=1;
|
||||
|
||||
/* setup the 5 bytes we have read so we get them from
|
||||
/* setup the 7 bytes we have read so we get them from
|
||||
* the sslv2 buffer */
|
||||
s->rstate=SSL_ST_READ_HEADER;
|
||||
s->packet_length=n;
|
||||
@@ -525,27 +525,13 @@ static int ssl23_get_server_hello(SSL *s)
|
||||
s->handshake_func=s->method->ssl_connect;
|
||||
#endif
|
||||
}
|
||||
else if ((p[0] == SSL3_RT_HANDSHAKE) &&
|
||||
(p[1] == SSL3_VERSION_MAJOR) &&
|
||||
((p[2] == SSL3_VERSION_MINOR) ||
|
||||
(p[2] == TLS1_VERSION_MINOR)) &&
|
||||
(p[5] == SSL3_MT_SERVER_HELLO))
|
||||
else if (p[1] == SSL3_VERSION_MAJOR &&
|
||||
((p[2] == SSL3_VERSION_MINOR) ||
|
||||
(p[2] == TLS1_VERSION_MINOR)) &&
|
||||
((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) ||
|
||||
(p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2)))
|
||||
{
|
||||
/* we have sslv3 or tls1 */
|
||||
|
||||
if (!ssl_init_wbio_buffer(s,1)) goto err;
|
||||
|
||||
/* we are in this state */
|
||||
s->state=SSL3_ST_CR_SRVR_HELLO_A;
|
||||
|
||||
/* put the 5 bytes we have read into the input buffer
|
||||
* for SSLv3 */
|
||||
s->rstate=SSL_ST_READ_HEADER;
|
||||
s->packet_length=n;
|
||||
s->packet= &(s->s3->rbuf.buf[0]);
|
||||
memcpy(s->packet,buf,n);
|
||||
s->s3->rbuf.left=n;
|
||||
s->s3->rbuf.offset=0;
|
||||
/* we have sslv3 or tls1 (server hello or alert) */
|
||||
|
||||
if ((p[2] == SSL3_VERSION_MINOR) &&
|
||||
!(s->options & SSL_OP_NO_SSLv3))
|
||||
@@ -572,35 +558,52 @@ static int ssl23_get_server_hello(SSL *s)
|
||||
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->handshake_func=s->method->ssl_connect;
|
||||
}
|
||||
else if ((p[0] == SSL3_RT_ALERT) &&
|
||||
(p[1] == SSL3_VERSION_MAJOR) &&
|
||||
((p[2] == SSL3_VERSION_MINOR) ||
|
||||
(p[2] == TLS1_VERSION_MINOR)) &&
|
||||
(p[3] == 0) &&
|
||||
(p[4] == 2))
|
||||
{
|
||||
void (*cb)(const SSL *ssl,int type,int val)=NULL;
|
||||
int j;
|
||||
|
||||
/* An alert */
|
||||
if (s->info_callback != NULL)
|
||||
cb=s->info_callback;
|
||||
else if (s->ctx->info_callback != NULL)
|
||||
cb=s->ctx->info_callback;
|
||||
|
||||
i=p[5];
|
||||
if (cb != NULL)
|
||||
if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
|
||||
{
|
||||
j=(i<<8)|p[6];
|
||||
cb(s,SSL_CB_READ_ALERT,j);
|
||||
/* fatal alert */
|
||||
|
||||
void (*cb)(const SSL *ssl,int type,int val)=NULL;
|
||||
int j;
|
||||
|
||||
if (s->info_callback != NULL)
|
||||
cb=s->info_callback;
|
||||
else if (s->ctx->info_callback != NULL)
|
||||
cb=s->ctx->info_callback;
|
||||
|
||||
i=p[5];
|
||||
if (cb != NULL)
|
||||
{
|
||||
j=(i<<8)|p[6];
|
||||
cb(s,SSL_CB_READ_ALERT,j);
|
||||
}
|
||||
|
||||
if (s->msg_callback)
|
||||
s->msg_callback(0, s->version, SSL3_RT_ALERT, p+5, 2, s, s->msg_callback_arg);
|
||||
|
||||
s->rwstate=SSL_NOTHING;
|
||||
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]);
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->rwstate=SSL_NOTHING;
|
||||
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]);
|
||||
goto err;
|
||||
if (!ssl_init_wbio_buffer(s,1)) goto err;
|
||||
|
||||
/* we are in this state */
|
||||
s->state=SSL3_ST_CR_SRVR_HELLO_A;
|
||||
|
||||
/* put the 7 bytes we have read into the input buffer
|
||||
* for SSLv3 */
|
||||
s->rstate=SSL_ST_READ_HEADER;
|
||||
s->packet_length=n;
|
||||
if (s->s3->rbuf.buf == NULL)
|
||||
if (!ssl3_setup_buffers(s))
|
||||
goto err;
|
||||
s->packet= &(s->s3->rbuf.buf[0]);
|
||||
memcpy(s->packet,buf,n);
|
||||
s->s3->rbuf.left=n;
|
||||
s->s3->rbuf.offset=0;
|
||||
|
||||
s->handshake_func=s->method->ssl_connect;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -758,6 +758,12 @@ int ssl3_alert_code(int code)
|
||||
case SSL_AD_INTERNAL_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE);
|
||||
case SSL_AD_USER_CANCELLED: return(SSL3_AD_HANDSHAKE_FAILURE);
|
||||
case SSL_AD_NO_RENEGOTIATION: return(-1); /* Don't send it :-) */
|
||||
case SSL_AD_UNSUPPORTED_EXTENSION: return(SSL3_AD_HANDSHAKE_FAILURE);
|
||||
case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(SSL3_AD_HANDSHAKE_FAILURE);
|
||||
case SSL_AD_UNRECOGNIZED_NAME: return(SSL3_AD_HANDSHAKE_FAILURE);
|
||||
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
|
||||
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
|
||||
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
|
||||
default: return(-1);
|
||||
}
|
||||
}
|
||||
|
@@ -1207,6 +1207,8 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
|
||||
#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
|
||||
#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME
|
||||
#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
|
||||
#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
|
||||
#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
|
||||
|
||||
#define SSL_ERROR_NONE 0
|
||||
#define SSL_ERROR_SSL 1
|
||||
@@ -2077,6 +2079,11 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022
|
||||
#define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048
|
||||
#define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090
|
||||
#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114
|
||||
#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113
|
||||
#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111
|
||||
#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112
|
||||
#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
|
||||
#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232
|
||||
#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 227
|
||||
#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
|
||||
|
@@ -475,6 +475,11 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW),"tlsv1 alert record overflow"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA),"tlsv1 alert unknown ca"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED),"tlsv1 alert user cancelled"},
|
||||
{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE),"tlsv1 bad certificate hash value"},
|
||||
{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE),"tlsv1 bad certificate status response"},
|
||||
{ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE),"tlsv1 certificate unobtainable"},
|
||||
{ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME),"tlsv1 unrecognized name"},
|
||||
{ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),"tlsv1 unsupported extension"},
|
||||
{ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),"tls client cert req with anon cipher"},
|
||||
{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"},
|
||||
{ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),"tls peer did not respond with certificate list"},
|
||||
|
@@ -414,6 +414,12 @@ const char *SSL_alert_desc_string(int value)
|
||||
case TLS1_AD_INTERNAL_ERROR: str="IE"; break;
|
||||
case TLS1_AD_USER_CANCELLED: str="US"; break;
|
||||
case TLS1_AD_NO_RENEGOTIATION: str="NR"; break;
|
||||
case TLS1_AD_UNSUPPORTED_EXTENSION: str="UE"; break;
|
||||
case TLS1_AD_CERTIFICATE_UNOBTAINABLE: str="CO"; break;
|
||||
case TLS1_AD_UNRECOGNIZED_NAME: str="UN"; break;
|
||||
case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: str="BR"; break;
|
||||
case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: str="BH"; break;
|
||||
case TLS1_AD_UNKNOWN_PSK_IDENTITY: str="UP"; break;
|
||||
default: str="UK"; break;
|
||||
}
|
||||
return(str);
|
||||
@@ -497,6 +503,24 @@ const char *SSL_alert_desc_string_long(int value)
|
||||
case TLS1_AD_NO_RENEGOTIATION:
|
||||
str="no renegotiation";
|
||||
break;
|
||||
case TLS1_AD_UNSUPPORTED_EXTENSION:
|
||||
str="unsupported extension";
|
||||
break;
|
||||
case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
|
||||
str="certificate unobtainable";
|
||||
break;
|
||||
case TLS1_AD_UNRECOGNIZED_NAME:
|
||||
str="unrecognized name";
|
||||
break;
|
||||
case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
|
||||
str="bad certificate status response";
|
||||
break;
|
||||
case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
|
||||
str="bad certificate hash value";
|
||||
break;
|
||||
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
|
||||
str="unknown PSK identity";
|
||||
break;
|
||||
default: str="unknown"; break;
|
||||
}
|
||||
return(str);
|
||||
|
@@ -853,6 +853,12 @@ int tls1_alert_code(int code)
|
||||
case SSL_AD_INTERNAL_ERROR: return(TLS1_AD_INTERNAL_ERROR);
|
||||
case SSL_AD_USER_CANCELLED: return(TLS1_AD_USER_CANCELLED);
|
||||
case SSL_AD_NO_RENEGOTIATION: return(TLS1_AD_NO_RENEGOTIATION);
|
||||
case SSL_AD_UNSUPPORTED_EXTENSION: return(TLS1_AD_UNSUPPORTED_EXTENSION);
|
||||
case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(TLS1_AD_CERTIFICATE_UNOBTAINABLE);
|
||||
case SSL_AD_UNRECOGNIZED_NAME: return(TLS1_AD_UNRECOGNIZED_NAME);
|
||||
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
|
||||
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
|
||||
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
|
||||
#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
|
||||
case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
|
||||
(DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
|
||||
|
Reference in New Issue
Block a user