예제 #1
0
void uwsgi_opt_sni(char *opt, char *value, void *foobar) {
        char *client_ca = NULL;
        char *v = uwsgi_str(value);

        char *space = strchr(v, ' ');
        if (!space) {
                uwsgi_log("invalid %s syntax, must be sni_key<space>crt,key[,ciphers,client_ca]\n", opt);
                exit(1);
        }
        *space = 0;
        char *crt = space+1;
        char *key = strchr(crt, ',');
        if (!key) {
                uwsgi_log("invalid %s syntax, must be sni_key<space>crt,key[,ciphers,client_ca]\n", opt);
                exit(1);
        }
        *key = '\0'; key++;

        char *ciphers = strchr(key, ',');
        if (ciphers) {
                *ciphers = '\0'; ciphers++;
                client_ca = strchr(ciphers, ',');
                if (client_ca) {
                        *client_ca = '\0'; client_ca++;
                }
        }

        if (!uwsgi.ssl_initialized) {
                uwsgi_ssl_init();
        }

        SSL_CTX *ctx = uwsgi_ssl_new_server_context(v, crt, key, ciphers, client_ca);
        if (!ctx) {
                uwsgi_log("[uwsgi-ssl] DANGER unable to initialize context for \"%s\"\n", v);
                free(v);
                return;
        }

#ifdef UWSGI_PCRE
        if (!strcmp(opt, "sni-regexp")) {
                struct uwsgi_regexp_list *url = uwsgi_regexp_new_list(&uwsgi.sni_regexp, v);
                url->custom_ptr = ctx;
        }
        else {
#endif
                struct uwsgi_string_list *usl = uwsgi_string_new_list(&uwsgi.sni, v);
                usl->custom_ptr = ctx;
#ifdef UWSGI_PCRE
        }
#endif

}
예제 #2
0
struct uwsgi_string_list *uwsgi_ssl_add_sni_item(char *name, char *crt, char *key, char *ciphers, char *client_ca) {
	if (!uwsgi.ssl_initialized) {
                uwsgi_ssl_init();
        }
	SSL_CTX *ctx = uwsgi_ssl_new_server_context(name, crt, key, ciphers, client_ca);
        if (!ctx) {
                uwsgi_log("[uwsgi-ssl] DANGER unable to initialize context for \"%s\"\n", name);
		return NULL;
	}

	struct uwsgi_string_list *usl = uwsgi_string_new_list(&uwsgi.sni, name);
	usl->custom_ptr = ctx;
	return usl;
}
예제 #3
0
void uwsgi_opt_https(char *opt, char *value, void *cr) {
        struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr;
        char *client_ca = NULL;

        // build socket, certificate and key file
        char *sock = uwsgi_str(value);
        char *crt = strchr(sock, ',');
        if (!crt) {
                uwsgi_log("invalid https syntax must be socket,crt,key\n");
                exit(1);
        }
        *crt = '\0'; crt++;
        char *key = strchr(crt, ',');
        if (!key) {
                uwsgi_log("invalid https syntax must be socket,crt,key\n");
                exit(1);
        }
        *key = '\0'; key++;

        char *ciphers = strchr(key, ',');
        if (ciphers) {
                *ciphers = '\0'; ciphers++;
                client_ca = strchr(ciphers, ',');
                if (client_ca) {
                        *client_ca = '\0'; client_ca++;
                }
        }

        struct uwsgi_gateway_socket *ugs = uwsgi_new_gateway_socket(sock, ucr->name);
        // ok we have the socket, initialize ssl if required
        if (!uwsgi.ssl_initialized) {
                uwsgi_ssl_init();
        }

        // initialize ssl context
	char *name = uhttp.https_session_context;
	if (!name) {
		name = uwsgi_concat3(ucr->short_name, "-", ugs->name);
	}

        ugs->ctx = uwsgi_ssl_new_server_context(name, crt, key, ciphers, client_ca);
	if (!ugs->ctx) {
		exit(1);
	}
        // set the ssl mode
        ugs->mode = UWSGI_HTTP_SSL;

        ucr->has_sockets++;
}
예제 #4
0
파일: sslrouter.c 프로젝트: chain710/uwsgi
static void uwsgi_opt_sslrouter2(char *opt, char *value, void *cr) {
        struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr;

        char *s2_addr = NULL;
        char *s2_cert = NULL;
        char *s2_key = NULL;
        char *s2_ciphers = NULL;
        char *s2_clientca = NULL;

        if (uwsgi_kvlist_parse(value, strlen(value), ',', '=',
                        "addr", &s2_addr,
                        "cert", &s2_cert,
                        "crt", &s2_cert,
                        "key", &s2_key,
                        "ciphers", &s2_ciphers,
                        "clientca", &s2_clientca,
                        "client_ca", &s2_clientca,
                        NULL)) {
                uwsgi_log("error parsing --sslrouter option\n");
                exit(1);
        }

        if (!s2_addr || !s2_cert || !s2_key) {
                uwsgi_log("--sslrouter option needs addr, cert and key items\n");
                exit(1);
        }

        struct uwsgi_gateway_socket *ugs = uwsgi_new_gateway_socket(s2_addr, ucr->name);
        // ok we have the socket, initialize ssl if required
        if (!uwsgi.ssl_initialized) {
                uwsgi_ssl_init();
        }
        
        // initialize ssl context
        char *name = usr.ssl_session_context;
        if (!name) {
                name = uwsgi_concat3(ucr->short_name, "-", ugs->name);
        }

	ugs->ctx = uwsgi_ssl_new_server_context(name, s2_cert, s2_key, s2_ciphers, s2_clientca);
        if (!ugs->ctx) {
                exit(1);
        }
        ucr->has_sockets++;
}
예제 #5
0
static void uwsgi_crypto_logger_setup_encryption(struct uwsgi_crypto_logger_conf *uclc) {

    if (!uwsgi.ssl_initialized) {
        uwsgi_ssl_init();
    }

    uclc->encrypt_ctx = uwsgi_malloc(sizeof(EVP_CIPHER_CTX));
    EVP_CIPHER_CTX_init(uclc->encrypt_ctx);

    const EVP_CIPHER *cipher = EVP_get_cipherbyname(uclc->algo);
    if (!cipher) {
        uwsgi_log_safe("[uwsgi-logcrypto] unable to find algorithm/cipher\n");
        exit(1);
    }
    int cipher_len = EVP_CIPHER_key_length(cipher);

    size_t s_len = strlen(uclc->secret);
    if ((unsigned int) cipher_len > s_len) {
        char *secret_tmp = uwsgi_malloc(cipher_len);
        memcpy(secret_tmp, uclc->secret, s_len);
        memset(secret_tmp + s_len, 0, cipher_len - s_len);
        uclc->secret = secret_tmp;
    }

    int iv_len = EVP_CIPHER_iv_length(cipher);
    size_t s_iv_len = 0;
    if (uclc->iv) {
        s_iv_len = strlen(uclc->iv);
    }
    if ((unsigned int) iv_len > s_iv_len) {
        char *secret_tmp = uwsgi_malloc(iv_len);
        memcpy(secret_tmp, uclc->iv, s_iv_len);
        memset(secret_tmp + s_iv_len, '0', iv_len - s_iv_len);
        uclc->iv = secret_tmp;
    }

    if (EVP_EncryptInit_ex(uclc->encrypt_ctx, cipher, NULL, (const unsigned char *) uclc->secret, (const unsigned char *) uclc->iv) <= 0) {
        uwsgi_error_safe("uwsgi_crypto_logger_setup_encryption()/EVP_EncryptInit_ex()");
        exit(1);
    }

}
예제 #6
0
char *uwsgi_rsa_sign(char *algo_key, char *message, size_t message_len, unsigned int *s_len) {

        // openssl could not be initialized
        if (!uwsgi.ssl_initialized) {
                uwsgi_ssl_init();
        }

        *s_len = 0;
        EVP_PKEY *pk = NULL;

        char *algo = uwsgi_str(algo_key);
        char *colon = strchr(algo, ':');
        if (!colon) {
                uwsgi_log("invalid RSA signature syntax, must be: <digest>:<pemfile>\n");
                free(algo);
                return NULL;
        }

        *colon = 0;
        char *keyfile = colon + 1;
        char *signature = NULL;

        FILE *kf = fopen(keyfile, "r");
        if (!kf) {
                uwsgi_error_open(keyfile);
                free(algo);
                return NULL;
        }

        if (PEM_read_PrivateKey(kf, &pk, NULL, NULL) == 0) {
                uwsgi_log("unable to load private key: %s\n", keyfile);
                free(algo);
                fclose(kf);
                return NULL;
        }

        fclose(kf);

        EVP_MD_CTX *ctx = EVP_MD_CTX_create();
        if (!ctx) {
                free(algo);
                EVP_PKEY_free(pk);
                return NULL;
        }

        const EVP_MD *md = EVP_get_digestbyname(algo);
        if (!md) {
                uwsgi_log("unknown digest algo: %s\n", algo);
                free(algo);
                EVP_PKEY_free(pk);
                EVP_MD_CTX_destroy(ctx);
                return NULL;
        }

        *s_len = EVP_PKEY_size(pk);
        signature = uwsgi_malloc(*s_len);

	if (EVP_SignInit_ex(ctx, md, NULL) == 0) {
                ERR_print_errors_fp(stderr);
                free(signature);
                signature = NULL;
                *s_len = 0;
                goto clear;
        }

        if (EVP_SignUpdate(ctx, message, message_len) == 0) {
                ERR_print_errors_fp(stderr);
                free(signature);
                signature = NULL;
                *s_len = 0;
                goto clear;
        }


        if (EVP_SignFinal(ctx, (unsigned char *) signature, s_len, pk) == 0) {
                ERR_print_errors_fp(stderr);
                free(signature);
                signature = NULL;
                *s_len = 0;
                goto clear;
        }

clear:
        free(algo);
        EVP_PKEY_free(pk);
        EVP_MD_CTX_destroy(ctx);
        return signature;

}
예제 #7
0
void uwsgi_opt_https2(char *opt, char *value, void *cr) {
        struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr;

	char *s2_addr = NULL;
	char *s2_cert = NULL;
	char *s2_key = NULL;
	char *s2_ciphers = NULL;
	char *s2_clientca = NULL;
	char *s2_spdy = NULL;

	if (uwsgi_kvlist_parse(value, strlen(value), ',', '=',
                        "addr", &s2_addr,
                        "cert", &s2_cert,
                        "crt", &s2_cert,
                        "key", &s2_key,
                        "ciphers", &s2_ciphers,
                        "clientca", &s2_clientca,
                        "client_ca", &s2_clientca,
                        "spdy", &s2_spdy,
                	NULL)) {
		uwsgi_log("error parsing --https2 option\n");
		exit(1);
        }

	if (!s2_addr || !s2_cert || !s2_key) {
		uwsgi_log("--https2 option needs addr, cert and key items\n");
		exit(1);
	}

        struct uwsgi_gateway_socket *ugs = uwsgi_new_gateway_socket(s2_addr, ucr->name);
        // ok we have the socket, initialize ssl if required
        if (!uwsgi.ssl_initialized) {
                uwsgi_ssl_init();
        }

        // initialize ssl context
        char *name = uhttp.https_session_context;
        if (!name) {
                name = uwsgi_concat3(ucr->short_name, "-", ugs->name);
        }

#ifdef UWSGI_SPDY
	if (s2_spdy) {
        	uhttp.spdy_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
		uhttp.spdy3_settings = uwsgi_buffer_new(uwsgi.page_size);
		if (uwsgi_buffer_append(uhttp.spdy3_settings, "\x80\x03\x00\x04\x01", 5)) goto spdyerror;
		if (uwsgi_buffer_u24be(uhttp.spdy3_settings, (8 * 2) + 4)) goto spdyerror;
		if (uwsgi_buffer_u32be(uhttp.spdy3_settings, 2)) goto spdyerror;

		// SETTINGS_ROUND_TRIP_TIME
		if (uwsgi_buffer_append(uhttp.spdy3_settings, "\x01\x00\x00\x03", 4)) goto spdyerror;
		if (uwsgi_buffer_u32be(uhttp.spdy3_settings, 30 * 1000)) goto spdyerror;
		// SETTINGS_INITIAL_WINDOW_SIZE
		if (uwsgi_buffer_append(uhttp.spdy3_settings, "\x01\x00\x00\x07", 4)) goto spdyerror;
		if (uwsgi_buffer_u32be(uhttp.spdy3_settings, 8192)) goto spdyerror;

		uhttp.spdy3_settings_size = uhttp.spdy3_settings->pos;
	}
#endif

        ugs->ctx = uwsgi_ssl_new_server_context(name, s2_cert, s2_key, s2_ciphers, s2_clientca);
        if (!ugs->ctx) {
                exit(1);
        }
#ifdef UWSGI_SPDY
	if (s2_spdy) {
        	SSL_CTX_set_info_callback(ugs->ctx, uwsgi_spdy_info_cb);
        	SSL_CTX_set_next_protos_advertised_cb(ugs->ctx, uwsgi_spdy_npn, NULL);
	}
#endif
        // set the ssl mode
        ugs->mode = UWSGI_HTTP_SSL;

        ucr->has_sockets++;

	return;

#ifdef UWSGI_SPDY
spdyerror:
	uwsgi_log("unable to initialize SPDY settings buffers\n");
	exit(1);
#endif
}