Exemplo n.º 1
0
/* Go through hello extensions in |b| and deserialize
 * them into the list in |ss->ssl3.hs.remoteExtensions|.
 * The only checking we do in this point is for duplicates.
 *
 * IMPORTANT: This list just contains pointers to the incoming
 * buffer so they can only be used during ClientHello processing.
 */
SECStatus
ssl3_ParseExtensions(sslSocket *ss, PRUint8 **b, PRUint32 *length)
{
    /* Clean out the extensions list. */
    ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);

    while (*length) {
        SECStatus rv;
        PRUint32 extension_type;
        SECItem extension_data = { siBuffer, NULL, 0 };
        TLSExtension *extension;
        PRCList *cursor;

        /* Get the extension's type field */
        rv = ssl3_ConsumeHandshakeNumber(ss, &extension_type, 2, b, length);
        if (rv != SECSuccess) {
            return SECFailure; /* alert already sent */
        }

        /* Check whether an extension has been sent multiple times. */
        for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions);
             cursor != &ss->ssl3.hs.remoteExtensions;
             cursor = PR_NEXT_LINK(cursor)) {
            if (((TLSExtension *)cursor)->type == extension_type) {
                (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
                PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION);
                return SECFailure;
            }
        }

        /* Get the data for this extension, so we can pass it or skip it. */
        rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length);
        if (rv != SECSuccess) {
            return rv; /* alert already sent */
        }

        SSL_TRC(10, ("%d: SSL3[%d]: parsed extension %d len=%u",
                     SSL_GETPID(), ss->fd, extension_type, extension_data.len));

        extension = PORT_ZNew(TLSExtension);
        if (!extension) {
            return SECFailure;
        }

        extension->type = (PRUint16)extension_type;
        extension->data = extension_data;
        PR_APPEND_LINK(&extension->link, &ss->ssl3.hs.remoteExtensions);
    }

    return SECSuccess;
}
Exemplo n.º 2
0
SECStatus
ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRUint32 *num,
                               PRUint32 bytes, PRUint8 **b, PRUint32 *length)
{
    return ssl3_ConsumeHandshakeNumber((sslSocket *)ss, num, bytes, b, length);
}
Exemplo n.º 3
0
static SECStatus
ssl_UpdateSupportedGroups(sslSocket *ss, SECItem *data)
{
    PRInt32 list_len;
    unsigned int i;
    const sslNamedGroupDef *enabled[SSL_NAMED_GROUP_COUNT] = { 0 };
    PORT_Assert(SSL_NAMED_GROUP_COUNT == PR_ARRAY_SIZE(enabled));

    if (!data->data || data->len < 4) {
        (void)ssl3_DecodeError(ss);
        return SECFailure;
    }

    /* get the length of elliptic_curve_list */
    list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
    if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) {
        (void)ssl3_DecodeError(ss);
        return SECFailure;
    }

    /* disable all groups and remember the enabled groups */
    for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
        enabled[i] = ss->namedGroupPreferences[i];
        ss->namedGroupPreferences[i] = NULL;
    }

    /* Read groups from data and enable if in |enabled| */
    while (data->len) {
        const sslNamedGroupDef *group;
        PRInt32 curve_name =
            ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
        if (curve_name < 0) {
            return SECFailure; /* fatal alert already sent */
        }
        group = ssl_LookupNamedGroup(curve_name);
        if (group) {
            for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
                if (enabled[i] && group == enabled[i]) {
                    ss->namedGroupPreferences[i] = enabled[i];
                    break;
                }
            }
        }

        /* "Codepoints in the NamedCurve registry with a high byte of 0x01 (that
         * is, between 256 and 511 inclusive) are set aside for FFDHE groups,"
         * -- https://tools.ietf.org/html/draft-ietf-tls-negotiated-ff-dhe-10
         */
        if ((curve_name & 0xff00) == 0x0100) {
            ss->ssl3.hs.peerSupportsFfdheGroups = PR_TRUE;
        }
    }

    /* Note: if ss->opt.requireDHENamedGroups is set, we disable DHE cipher
     * suites, but we do that in ssl3_config_match(). */
    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 &&
        !ss->opt.requireDHENamedGroups && !ss->ssl3.hs.peerSupportsFfdheGroups) {
        /* If we don't require that DHE use named groups, and no FFDHE was
         * included, we pretend that they support all the FFDHE groups we do. */
        for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) {
            if (enabled[i] && enabled[i]->keaType == ssl_kea_dh) {
                ss->namedGroupPreferences[i] = enabled[i];
            }
        }
    }

    return SECSuccess;
}