Пример #1
0
/*
 * With a NULL context, this function just checks that the serverinfo data
 * parses correctly.  With a non-NULL context, it registers callbacks for
 * the included extensions.
 */
static int serverinfo_process_buffer(const unsigned char *serverinfo,
                                     size_t serverinfo_length, SSL_CTX *ctx)
{
    if (serverinfo == NULL || serverinfo_length == 0)
        return 0;
    for (;;) {
        unsigned int ext_type = 0;
        size_t len = 0;

        /* end of serverinfo */
        if (serverinfo_length == 0)
            return 1;

        /* read 2-byte type field */
        if (serverinfo_length < 2)
            return 0;
        /* FIXME: check for types we understand explicitly? */

        /* Register callbacks for extensions */
        ext_type = (serverinfo[0] << 8) + serverinfo[1];
        if (ctx) {
            int have_ext_cbs = 0;
            size_t i;
            custom_ext_methods *exts = &ctx->cert->srv_ext;
            custom_ext_method *meth = exts->meths;

            for (i = 0; i < exts->meths_count; i++, meth++) {
                if (ext_type == meth->ext_type) {
                    have_ext_cbs = 1;
                    break;
                }
            }

            if (!have_ext_cbs && !SSL_CTX_add_server_custom_ext(ctx, ext_type,
                                                                serverinfo_srv_add_cb,
                                                                NULL, NULL,
                                                                serverinfo_srv_parse_cb,
                                                                NULL))
                return 0;
        }

        serverinfo += 2;
        serverinfo_length -= 2;

        /* read 2-byte len field */
        if (serverinfo_length < 2)
            return 0;
        len = (serverinfo[0] << 8) + serverinfo[1];
        serverinfo += 2;
        serverinfo_length -= 2;

        if (len > serverinfo_length)
            return 0;

        serverinfo += len;
        serverinfo_length -= len;
    }
}
Пример #2
0
/* With a NULL context, this function just checks that the serverinfo data
   parses correctly.  With a non-NULL context, it registers callbacks for 
   the included extensions. */
static int serverinfo_process_buffer(const unsigned char *serverinfo, 
			    	     size_t serverinfo_length, SSL_CTX *ctx)
	{
	if (serverinfo == NULL || serverinfo_length == 0)
		return 0;
	for (;;)
		{
		unsigned int ext_type = 0;
		size_t len = 0;

		/* end of serverinfo */
		if (serverinfo_length == 0)
			return 1;

		/* read 2-byte type field */
		if (serverinfo_length < 2)
			return 0;
		/* FIXME: check for types we understand explicitly? */

		/* Register callbacks for extensions */
		ext_type = (serverinfo[0] << 8) + serverinfo[1];
		if (ctx && !SSL_CTX_add_server_custom_ext(ctx, ext_type, 
							  serverinfo_srv_add_cb,
							  NULL, NULL,
							  serverinfo_srv_parse_cb, 
							  NULL))
			return 0;

		serverinfo += 2;
		serverinfo_length -= 2;

		/* read 2-byte len field */
		if (serverinfo_length < 2)
			return 0;
		len = (serverinfo[0] << 8) + serverinfo[1];
		serverinfo += 2;
		serverinfo_length -= 2;

		if (len > serverinfo_length)
			return 0;

		serverinfo += len;
		serverinfo_length -= len;
		}
	}
Пример #3
0
/*
 * Custom call back tests.
 * Test 0: callbacks in TLSv1.2
 * Test 1: callbacks in TLSv1.2 with SNI
 */
static int test_custom_exts(int tst)
{
    SSL_CTX *cctx = NULL, *sctx = NULL, *sctx2 = NULL;
    SSL *clientssl = NULL, *serverssl = NULL;
    int testresult = 0;
    static int server = 1;
    static int client = 0;
    SSL_SESSION *sess = NULL;

    /* Reset callback counters */
    clntaddcb = clntparsecb = srvaddcb = srvparsecb = 0;
    snicb = 0;

    if (!create_ssl_ctx_pair(TLS_server_method(),  TLS_client_method(), &sctx,
                             &cctx, cert, privkey)) {
        printf("Unable to create SSL_CTX pair\n");
        goto end;
    }

    if (tst == 1
            && !create_ssl_ctx_pair(TLS_server_method(), NULL, &sctx2, NULL,
                                    cert, privkey)) {
        printf("Unable to create SSL_CTX pair (2)\n");
        goto end;
    }

    /* Create a client side custom extension */
    if (!SSL_CTX_add_client_custom_ext(cctx, TEST_EXT_TYPE1, add_cb, free_cb,
                                       &client, parse_cb, &client)) {
        printf("Unable to add client custom extension\n");
        goto end;
    }

    /* Should not be able to add duplicates */
    if (SSL_CTX_add_client_custom_ext(cctx, TEST_EXT_TYPE1, add_cb, free_cb,
                                      &client, parse_cb, &client)) {
        printf("Unexpected success adding duplicate extension\n");
        goto end;
    }

    /* Create a server side custom extension */
    if (!SSL_CTX_add_server_custom_ext(sctx, TEST_EXT_TYPE1, add_cb, free_cb,
                                       &server, parse_cb, &server)) {
        printf("Unable to add server custom extension\n");
        goto end;
    }
    if (sctx2 != NULL
            && !SSL_CTX_add_server_custom_ext(sctx2, TEST_EXT_TYPE1,
                                                        add_cb, free_cb,
                                                        &server, parse_cb,
                                                        &server)) {
        printf("Unable to add server custom extension for SNI\n");
        goto end;
    }

    /* Should not be able to add duplicates */
    if (SSL_CTX_add_server_custom_ext(sctx, TEST_EXT_TYPE1, add_cb, free_cb,
                                      &server, parse_cb, &server)) {
        printf("Unexpected success adding duplicate extension (2)\n");
        goto end;
    }

    if (tst == 1) {
        /* Set up SNI */
        if (!SSL_CTX_set_tlsext_servername_callback(sctx, sni_cb)
                || !SSL_CTX_set_tlsext_servername_arg(sctx, sctx2)) {
            printf("Cannot set SNI callbacks\n");
            goto end;
        }
    }

    if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)
            || !create_ssl_connection(serverssl, clientssl)) {
        printf("Cannot create SSL connection\n");
        goto end;
    }

    if (clntaddcb != 1
            || clntparsecb != 1
            || srvaddcb != 1
            || srvparsecb != 1
            || (tst != 1 && snicb != 0)
            || (tst == 1 && snicb != 1)) {
        printf("Incorrect callback counts\n");
        goto end;
    }

    sess = SSL_get1_session(clientssl);
    SSL_shutdown(clientssl);
    SSL_shutdown(serverssl);
    SSL_free(serverssl);
    SSL_free(clientssl);
    serverssl = clientssl = NULL;

    if (tst == 1) {
        /* We don't bother with the resumption aspects for this test */
        testresult = 1;
        goto end;
    }

    if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)
            || !SSL_set_session(clientssl, sess)
            || !create_ssl_connection(serverssl, clientssl)) {
        printf("Cannot create resumption connection\n");
        goto end;
    }

    /*
     * For a resumed session we expect to add the ClientHello extension but we
     * should ignore it on the server side.
     */
    if (clntaddcb != 2
            || clntparsecb != 1
            || srvaddcb != 1
            || srvparsecb != 1) {
        printf("Incorrect resumption callback counts\n");
        goto end;
    }

    testresult = 1;

end:
    SSL_SESSION_free(sess);
    SSL_free(serverssl);
    SSL_free(clientssl);
    SSL_CTX_free(sctx2);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);
    return testresult;
}
Пример #4
0
static char *ngx_http_ssl_ct_merge_srv_conf(ngx_conf_t *cf, void *parent,
    void *child)
{
    /* merge config */
    ngx_ssl_ct_srv_conf_t *prev = parent;
    ngx_ssl_ct_srv_conf_t *conf = child;

    ngx_conf_merge_value(conf->enable, prev->enable, 0);
    ngx_conf_merge_str_value(conf->sct, prev->sct, "");

    /* validate config */
    if (conf->enable)
    {
        if (conf->sct.len == 0)
        {
            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                "no \"ssl_ct_static_scts\" is defined for the \"ssl_ct\""
                "directive");
            return NGX_CONF_ERROR;
        }
    }
    else
    {
        return NGX_CONF_OK;
    }

    /* get ngx_http_ssl_module configuration and check if SSL is enabled */
    ngx_http_ssl_srv_conf_t *ssl_conf = ngx_http_conf_get_module_srv_conf(cf,
        ngx_http_ssl_module);

    if (!ssl_conf->ssl.ctx)
    {
        ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
            "\"ssl_ct\" can only be enabled if ssl is enabled");
        return NGX_CONF_ERROR;
    }

    /* read .sct files */
    ngx_ssl_ct_ext *sct_list = ngx_ssl_ct_read_static_scts(cf, &conf->sct);
    if (!sct_list)
    {
        /* ngx_ssl_ct_read_static_scts calls ngx_log_error */
        return NGX_CONF_ERROR;
    }

    /* add OpenSSL TLS extension */
#ifndef OPENSSL_IS_BORINGSSL
    if (SSL_CTX_add_server_custom_ext(ssl_conf->ssl.ctx, NGX_SSL_CT_EXT,
        &ngx_ssl_ct_ext_cb, NULL, sct_list, NULL, NULL) == 0)
    {
        ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
            "SSL_CTX_add_server_custom_ext failed");
        ngx_pfree(cf->pool, sct_list);
        return NGX_CONF_ERROR;
    }
#else
    if (SSL_CTX_set_signed_cert_timestamp_list(ssl_conf->ssl.ctx, sct_list->buf,
        sct_list->len) == 0)
    {
        ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
            "SSL_CTX_set_signed_cert_timestamp_list failed");
        ngx_pfree(cf->pool, sct_list);
        return NGX_CONF_ERROR;
    }
#endif

    return NGX_CONF_OK;
}