/* Send our "canned" (precompiled) Supported Point Formats extension, * which says that we only support uncompressed points. */ PRInt32 ssl3_SendSupportedPointFormatsXtn( sslSocket *ss, PRBool append, PRUint32 maxBytes) { static const PRUint8 ecPtFmt[6] = { 0, 11, /* Extension type */ 0, 2, /* octets that follow */ 1, /* octets that follow */ 0 /* uncompressed type only */ }; /* No point in doing this unless we have a socket that supports ECC. * Similarly, no point if we are going to do TLS 1.3 only or we have already * picked TLS 1.3 (server) given that it doesn't use point formats. */ if (!ss || !ssl_IsECCEnabled(ss) || ss->vrange.min >= SSL_LIBRARY_VERSION_TLS_1_3 || (ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)) return 0; if (append && maxBytes >= (sizeof ecPtFmt)) { SECStatus rv = ssl3_AppendHandshake(ss, ecPtFmt, (sizeof ecPtFmt)); if (rv != SECSuccess) return -1; if (!ss->sec.isServer) { TLSExtensionData *xtnData = &ss->xtnData; xtnData->advertised[xtnData->numAdvertised++] = ssl_ec_point_formats_xtn; } } return sizeof(ecPtFmt); }
/* Send our Supported Groups extension. */ PRInt32 ssl_SendSupportedGroupsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) { PRInt32 extension_length; unsigned char enabledGroups[64]; unsigned int enabledGroupsLen = 0; unsigned int i; PRBool ec; PRBool ff = PR_FALSE; if (!ss) return 0; ec = ssl_IsECCEnabled(ss); /* We only send FF supported groups if we require DH named groups or if TLS * 1.3 is a possibility. */ if (ss->opt.requireDHENamedGroups || ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3) { ff = ssl_IsSuiteEnabled(ss, ssl_dhe_suites); } if (!ec && !ff) { return 0; } PORT_Assert(sizeof(enabledGroups) > ssl_named_group_count * 2); for (i = 0; i < ssl_named_group_count; ++i) { if (ssl_named_groups[i].type == group_type_ec && !ec) { continue; } if (ssl_named_groups[i].type == group_type_ff && !ff) { continue; } if (!ssl_NamedGroupEnabled(ss, &ssl_named_groups[i])) { continue; } if (append) { enabledGroups[enabledGroupsLen++] = ssl_named_groups[i].name >> 8; enabledGroups[enabledGroupsLen++] = ssl_named_groups[i].name & 0xff; } else { enabledGroupsLen += 2; } }
/* Send our Supported Groups extension. */ PRInt32 ssl_SendSupportedGroupsXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) { PRInt32 extension_length; unsigned char enabledGroups[64]; unsigned int enabledGroupsLen = 0; unsigned int i; PRBool ec; PRBool ff = PR_FALSE; if (!ss) return 0; /* We only send FF supported groups if we require DH named groups * or if TLS 1.3 is a possibility. */ if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) { ec = ssl_IsECCEnabled(ss); if (ss->opt.requireDHENamedGroups) { ff = ssl_IsDHEEnabled(ss); } if (!ec && !ff) return 0; } else { ec = ff = PR_TRUE; } PORT_Assert(sizeof(enabledGroups) > SSL_NAMED_GROUP_COUNT * 2); for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) { const sslNamedGroupDef *group = ss->namedGroupPreferences[i]; if (!group) { continue; } if (group->keaType == ssl_kea_ecdh && !ec) { continue; } if (group->keaType == ssl_kea_dh && !ff) { continue; } if (append) { (void)ssl_EncodeUintX(group->name, 2, &enabledGroups[enabledGroupsLen]); } enabledGroupsLen += 2; } if (enabledGroupsLen == 0) { return 0; } extension_length = 2 /* extension type */ + 2 /* extension length */ + 2 /* enabled groups length */ + enabledGroupsLen; if (maxBytes < (PRUint32)extension_length) { return 0; } if (append) { SECStatus rv; rv = ssl3_AppendHandshakeNumber(ss, ssl_supported_groups_xtn, 2); if (rv != SECSuccess) return -1; rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); if (rv != SECSuccess) return -1; rv = ssl3_AppendHandshakeVariable(ss, enabledGroups, enabledGroupsLen, 2); if (rv != SECSuccess) return -1; if (!ss->sec.isServer) { TLSExtensionData *xtnData = &ss->xtnData; xtnData->advertised[xtnData->numAdvertised++] = ssl_supported_groups_xtn; } } return extension_length; }