Store groups as uint16_t
Instead of storing supported groups in on-the-wire format store
them as parsed uint16_t values. This simplifies handling of groups
as the values can be directly used instead of being converted.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4406)
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
index 61203ed..8b88b21 100644
--- a/ssl/statem/extensions.c
+++ b/ssl/statem/extensions.c
@@ -1137,7 +1137,7 @@
&& (!s->hit
|| (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE)
!= 0)) {
- const unsigned char *pcurves, *pcurvestmp, *clntcurves;
+ const uint16_t *pcurves, *clntcurves;
size_t num_curves, clnt_num_curves, i;
unsigned int group_id = 0;
@@ -1158,9 +1158,8 @@
}
/* Find the first group we allow that is also in client's list */
- for (i = 0, pcurvestmp = pcurves; i < num_curves;
- i++, pcurvestmp += 2) {
- group_id = bytestogroup(pcurvestmp);
+ for (i = 0; i < num_curves; i++) {
+ group_id = pcurves[i];
if (check_in_list(s, group_id, clntcurves, clnt_num_curves, 1))
break;
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index bffe7ac..6975b94 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -139,7 +139,7 @@
unsigned int context, X509 *x,
size_t chainidx, int *al)
{
- const unsigned char *pcurves = NULL, *pcurvestmp;
+ const uint16_t *pcurves = NULL;
size_t num_curves = 0, i;
if (!use_ecc(s))
@@ -154,7 +154,6 @@
ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
- pcurvestmp = pcurves;
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_supported_groups)
/* Sub-packet for supported_groups extension */
@@ -165,10 +164,11 @@
return EXT_RETURN_FAIL;
}
/* Copy curve ID if supported */
- for (i = 0; i < num_curves; i++, pcurvestmp += 2) {
- if (tls_curve_allowed(s, pcurvestmp, SSL_SECOP_CURVE_SUPPORTED)) {
- if (!WPACKET_put_bytes_u8(pkt, pcurvestmp[0])
- || !WPACKET_put_bytes_u8(pkt, pcurvestmp[1])) {
+ for (i = 0; i < num_curves; i++) {
+ uint16_t ctmp = pcurves[i];
+
+ if (tls_curve_allowed(s, ctmp, SSL_SECOP_CURVE_SUPPORTED)) {
+ if (!WPACKET_put_bytes_u16(pkt, ctmp)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_GROUPS,
ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
@@ -595,8 +595,8 @@
{
#ifndef OPENSSL_NO_TLS1_3
size_t i, num_curves = 0;
- const unsigned char *pcurves = NULL;
- unsigned int curve_id = 0;
+ const uint16_t *pcurves = NULL;
+ uint16_t curve_id = 0;
/* key_share extension */
if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share)
@@ -620,12 +620,12 @@
if (s->s3->group_id != 0) {
curve_id = s->s3->group_id;
} else {
- for (i = 0; i < num_curves; i++, pcurves += 2) {
+ for (i = 0; i < num_curves; i++) {
- if (!tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED))
+ if (!tls_curve_allowed(s, pcurves[i], SSL_SECOP_CURVE_SUPPORTED))
continue;
- curve_id = bytestogroup(pcurves);
+ curve_id = pcurves[i];
break;
}
}
@@ -1521,7 +1521,7 @@
}
if ((context & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0) {
- unsigned const char *pcurves = NULL;
+ const uint16_t *pcurves = NULL;
size_t i, num_curves;
if (PACKET_remaining(pkt) != 0) {
@@ -1545,12 +1545,12 @@
SSLerr(SSL_F_TLS_PARSE_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR);
return 0;
}
- for (i = 0; i < num_curves; i++, pcurves += 2) {
- if (group_id == bytestogroup(pcurves))
+ for (i = 0; i < num_curves; i++) {
+ if (group_id == pcurves[i])
break;
}
if (i >= num_curves
- || !tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) {
+ || !tls_curve_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED)) {
*al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_PARSE_STOC_KEY_SHARE, SSL_R_BAD_KEY_SHARE);
return 0;
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index 0dbec91..583b8dd 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -499,7 +499,7 @@
#ifndef OPENSSL_NO_TLS1_3
unsigned int group_id;
PACKET key_share_list, encoded_pt;
- const unsigned char *clntcurves, *srvrcurves;
+ const uint16_t *clntcurves, *srvrcurves;
size_t clnt_num_curves, srvr_num_curves;
int group_nid, found = 0;
unsigned int curve_flags;
@@ -647,7 +647,7 @@
OPENSSL_free(s->session->ext.supportedgroups);
s->session->ext.supportedgroups = NULL;
s->session->ext.supportedgroups_len = 0;
- if (!PACKET_memdup(&supported_groups_list,
+ if (!tls1_save_u16(&supported_groups_list,
&s->session->ext.supportedgroups,
&s->session->ext.supportedgroups_len)) {
*al = SSL_AD_INTERNAL_ERROR;
@@ -917,7 +917,7 @@
unsigned int context, X509 *x,
size_t chainidx, int *al)
{
- const unsigned char *groups;
+ const uint16_t *groups;
size_t numgroups, i, first = 1;
/* s->s3->group_id is non zero if we accepted a key_share */
@@ -931,14 +931,16 @@
}
/* Copy group ID if supported */
- for (i = 0; i < numgroups; i++, groups += 2) {
- if (tls_curve_allowed(s, groups, SSL_SECOP_CURVE_SUPPORTED)) {
+ for (i = 0; i < numgroups; i++) {
+ uint16_t group = groups[i];
+
+ if (tls_curve_allowed(s, group, SSL_SECOP_CURVE_SUPPORTED)) {
if (first) {
/*
* Check if the client is already using our preferred group. If
* so we don't need to add this extension
*/
- if (s->s3->group_id == GET_GROUP_ID(groups, 0))
+ if (s->s3->group_id == group)
return EXT_RETURN_NOT_SENT;
/* Add extension header */
@@ -953,7 +955,7 @@
first = 0;
}
- if (!WPACKET_put_bytes_u16(pkt, GET_GROUP_ID(groups, 0))) {
+ if (!WPACKET_put_bytes_u16(pkt, group)) {
SSLerr(SSL_F_TLS_CONSTRUCT_STOC_SUPPORTED_GROUPS,
ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index d296243..84ad2f6 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -1964,7 +1964,7 @@
* 1) or 0 otherwise.
*/
#ifndef OPENSSL_NO_EC
-int check_in_list(SSL *s, unsigned int group_id, const unsigned char *groups,
+int check_in_list(SSL *s, uint16_t group_id, const uint16_t *groups,
size_t num_groups, int checkallow)
{
size_t i;
@@ -1972,10 +1972,12 @@
if (groups == NULL || num_groups == 0)
return 0;
- for (i = 0; i < num_groups; i++, groups += 2) {
- if (group_id == GET_GROUP_ID(groups, 0)
+ for (i = 0; i < num_groups; i++) {
+ uint16_t group = groups[i];
+
+ if (group_id == group
&& (!checkallow
- || tls_curve_allowed(s, groups, SSL_SECOP_CURVE_CHECK))) {
+ || tls_curve_allowed(s, group, SSL_SECOP_CURVE_CHECK))) {
return 1;
}
}
diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h
index ae33fe5..9b76dc0 100644
--- a/ssl/statem/statem_locl.h
+++ b/ssl/statem/statem_locl.h
@@ -55,10 +55,7 @@
typedef int (*confunc_f) (SSL *s, WPACKET *pkt);
-#define GET_GROUP_ID(group, idx) \
- (unsigned int)(((group)[(idx) * 2] << 8) | (group)[((idx) * 2) + 1])
-
-int check_in_list(SSL *s, unsigned int group_id, const unsigned char *groups,
+int check_in_list(SSL *s, uint16_t group_id, const uint16_t *groups,
size_t num_groups, int checkallow);
int create_synthetic_message_hash(SSL *s);
int parse_ca_names(SSL *s, PACKET *pkt, int *al);