Beispiel #1
0
static int openssl_ssl_ctx_new_bio(lua_State*L)
{
  SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx");
  const char* host_addr = luaL_checkstring(L, 2);
  int server = lua_isnoneornil(L, 3) ? 0 : auxiliar_checkboolean(L, 3);
  int autoretry = lua_isnoneornil(L, 4) ? 1 : auxiliar_checkboolean(L, 4);

  SSL *ssl = NULL;
  BIO *bio = server ? BIO_new_ssl(ctx, 0) : BIO_new_ssl_connect(ctx);
  int ret = BIO_get_ssl(bio, &ssl);
  if (ret == 1 && ssl)
  {
    if (autoretry)
      SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    if (server)
    {
      BIO* acpt = BIO_new_accept((char*)host_addr);
      BIO_set_accept_bios(acpt, bio);
      bio = acpt;
    }
    else
    {
      ret = BIO_set_conn_hostname(bio, host_addr);
    }
    if (ret == 1)
    {
      PUSH_OBJECT(bio, "openssl.bio");
      openssl_newvalue(L, bio);

      lua_pushboolean(L, 1);
      openssl_setvalue(L, bio, "free_all");

      return 1;
    }
    else
      return openssl_pushresult(L, ret);
  }
  else
  {
    BIO_free(bio);
    bio = NULL;
    return 0;
  }
}
Beispiel #2
0
static BIO *
start_tls(SSL_CTX *ctx)
{
    AUTO(BIO, sio);
    SSL *ssl;

    sio = BIO_new_ssl(ctx, 0);
    if (sio == NULL)
        return NULL;

    if (BIO_get_ssl(sio, &ssl) <= 0)
        return NULL;

    if (SSL_set_fd(ssl, SD_LISTEN_FDS_START) <= 0)
        return NULL;

    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    return STEAL(sio);
}
Beispiel #3
0
static bool
do_accept(SSL_CTX *ctx, int fd, int *client, BIO **sio)
{
    SSL *ssl;

    *client = accept(fd, NULL, NULL);
    if (*client < 0)
        return false;

    *sio = BIO_new_ssl(ctx, 0);
    if (*sio == NULL)
        return false;

    if (BIO_get_ssl(*sio, &ssl) <= 0)
        return false;

    if (SSL_set_fd(ssl, *client) <= 0)
        return false;

    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    return true;
}
Beispiel #4
0
HTTPScode
https_open(struct https_request **reqp, const char *host)
{
        struct https_request *req;
        BIO *b64, *sbio;
        char *p;
        int n;
        int connection_error = 0;
        const char *api_host;
        const char *api_port;

        /* Set up our handle */
        n = 1;
        if ((req = calloc(1, sizeof(*req))) == NULL ||
            (req->host = strdup(host)) == NULL ||
            (req->parser = malloc(sizeof(http_parser))) == NULL) {
                ctx->errstr = strerror(errno);
                https_close(&req);
                return (HTTPS_ERR_SYSTEM);
        }
        if ((p = strchr(req->host, ':')) != NULL) {
                *p = '\0';
                req->port = p + 1;
        } else {
                req->port = "443";
        }
        if ((req->body = BIO_new(BIO_s_mem())) == NULL) {
                ctx->errstr = _SSL_strerror();
                https_close(&req);
                return (HTTPS_ERR_LIB);
        }
        http_parser_init(req->parser, HTTP_RESPONSE);
        req->parser->data = req;

        /* Connect to server */
        if (ctx->proxy) {
            api_host = ctx->proxy;
            api_port = ctx->proxy_port;
        } else {
            api_host = req->host;
            api_port = req->port;
        }
        connection_error = _establish_connection(req, api_host, api_port);
        if (connection_error != HTTPS_OK) {
            https_close(&req);
            return connection_error;
        }

        /* Tunnel through proxy, if specified */
        if (ctx->proxy != NULL) {
                BIO_printf(req->cbio,
                    "CONNECT %s:%s HTTP/1.0\r\n"
                    "User-Agent: %s\r\n",
                    req->host, req->port, ctx->useragent);
                
                if (ctx->proxy_auth != NULL) {
                        b64 = BIO_push(BIO_new(BIO_f_base64()),
                            BIO_new(BIO_s_mem()));
                        BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
                        BIO_write(b64, ctx->proxy_auth,
                            strlen(ctx->proxy_auth));
                        (void)BIO_flush(b64);
                        n = BIO_get_mem_data(b64, &p);

                        BIO_puts(req->cbio, "Proxy-Authorization: Basic ");
                        BIO_write(req->cbio, p, n);
                        BIO_puts(req->cbio, "\r\n");
                        BIO_free_all(b64);
                }
                BIO_puts(req->cbio, "\r\n");
                (void)BIO_flush(req->cbio);
                
                while ((n = BIO_read(req->cbio, ctx->parse_buf,
                            sizeof(ctx->parse_buf))) <= 0) {
                        _BIO_wait(req->cbio, 5000);
                }
                if (strncmp("HTTP/1.0 200", ctx->parse_buf, 12) != 0) {
                        snprintf(ctx->errbuf, sizeof(ctx->errbuf),
                            "Proxy error: %s", ctx->parse_buf);
                        ctx->errstr = strtok(ctx->errbuf, "\r\n");
                        https_close(&req);
                        if (n < 12 || atoi(ctx->parse_buf + 9) < 500)
                                return (HTTPS_ERR_CLIENT);
                        return (HTTPS_ERR_SERVER);
                }
        }
        /* Establish SSL connection */
        if ((sbio = BIO_new_ssl(ctx->ssl_ctx, 1)) == NULL) {
                https_close(&req);
                return (HTTPS_ERR_LIB);
        }
        req->cbio = BIO_push(sbio, req->cbio);
        BIO_get_ssl(req->cbio, &req->ssl);
        
        while (BIO_do_handshake(req->cbio) <= 0) {
                if ((n = _BIO_wait(req->cbio, 5000)) != 1) {
                        ctx->errstr = n ? _SSL_strerror() :
                            "SSL handshake timed out";
                        https_close(&req);
                        return (n ? HTTPS_ERR_SYSTEM : HTTPS_ERR_SERVER);
                }
        }
        /* Validate server certificate name */
        if (_SSL_check_server_cert(req->ssl, req->host) != 1) {
                ctx->errstr = "Certificate name validation failed";
                https_close(&req);
                return (HTTPS_ERR_LIB);
        }
        *reqp = req;
        
        return (HTTPS_OK);
}
Beispiel #5
0
int main(int argc, char *argv[])
{
    char *port = "*:4433";
    BIO *in = NULL;
    BIO *ssl_bio, *tmp;
    SSL_CTX *ctx;
    SSL_CONF_CTX *cctx = NULL;
    CONF *conf = NULL;
    STACK_OF(CONF_VALUE) *sect = NULL;
    CONF_VALUE *cnf;
    long errline = -1;
    char buf[512];
    int ret = EXIT_FAILURE, i;

    ctx = SSL_CTX_new(TLS_server_method());

    conf = NCONF_new(NULL);

    if (NCONF_load(conf, "accept.cnf", &errline) <= 0) {
        if (errline <= 0)
            fprintf(stderr, "Error processing config file\n");
        else
            fprintf(stderr, "Error on line %ld\n", errline);
        goto err;
    }

    sect = NCONF_get_section(conf, "default");

    if (sect == NULL) {
        fprintf(stderr, "Error retrieving default section\n");
        goto err;
    }

    cctx = SSL_CONF_CTX_new();
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
    SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
    for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
        int rv;
        cnf = sk_CONF_VALUE_value(sect, i);
        rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value);
        if (rv > 0)
            continue;
        if (rv != -2) {
            fprintf(stderr, "Error processing %s = %s\n",
                    cnf->name, cnf->value);
            ERR_print_errors_fp(stderr);
            goto err;
        }
        if (strcmp(cnf->name, "Port") == 0) {
            port = cnf->value;
        } else {
            fprintf(stderr, "Unknown configuration option %s\n", cnf->name);
            goto err;
        }
    }

    if (!SSL_CONF_CTX_finish(cctx)) {
        fprintf(stderr, "Finish error\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }

    /* Setup server side SSL bio */
    ssl_bio = BIO_new_ssl(ctx, 0);

    if ((in = BIO_new_accept(port)) == NULL)
        goto err;

    /*
     * This means that when a new connection is accepted on 'in', The ssl_bio
     * will be 'duplicated' and have the new socket BIO push into it.
     * Basically it means the SSL BIO will be automatically setup
     */
    BIO_set_accept_bios(in, ssl_bio);

 again:
    /*
     * The first call will setup the accept socket, and the second will get a
     * socket.  In this loop, the first actual accept will occur in the
     * BIO_read() function.
     */

    if (BIO_do_accept(in) <= 0)
        goto err;

    for (;;) {
        i = BIO_read(in, buf, 512);
        if (i == 0) {
            /*
             * If we have finished, remove the underlying BIO stack so the
             * next time we call any function for this BIO, it will attempt
             * to do an accept
             */
            printf("Done\n");
            tmp = BIO_pop(in);
            BIO_free_all(tmp);
            goto again;
        }
        if (i < 0) {
            if (BIO_should_retry(in))
                continue;
            goto err;
        }
        fwrite(buf, 1, i, stdout);
        fflush(stdout);
    }

    ret = EXIT_SUCCESS;
 err:
    if (ret != EXIT_SUCCESS)
        ERR_print_errors_fp(stderr);
    BIO_free(in);
    return ret;
}
Beispiel #6
0
int main(int argc, char *argv[])
{
    char *port = "*:4433";
    BIO *ssl_bio, *tmp;
    SSL_CTX *ctx;
    SSL_CONF_CTX *cctx;
    char buf[512];
    BIO *in = NULL;
    int ret = 1, i;
    char **args = argv + 1;
    int nargs = argc - 1;

    SSL_load_error_strings();

    /* Add ciphers and message digests */
    OpenSSL_add_ssl_algorithms();

    ctx = SSL_CTX_new(SSLv23_server_method());

    cctx = SSL_CONF_CTX_new();
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
    SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
    while (*args && **args == '-') {
        int rv;
        /* Parse standard arguments */
        rv = SSL_CONF_cmd_argv(cctx, &nargs, &args);
        if (rv == -3) {
            fprintf(stderr, "Missing argument for %s\n", *args);
            goto err;
        }
        if (rv < 0) {
            fprintf(stderr, "Error in command %s\n", *args);
            ERR_print_errors_fp(stderr);
            goto err;
        }
        /* If rv > 0 we processed something so proceed to next arg */
        if (rv > 0)
            continue;
        /* Otherwise application specific argument processing */
        if (strcmp(*args, "-port") == 0) {
            port = args[1];
            if (port == NULL) {
                fprintf(stderr, "Missing -port argument\n");
                goto err;
            }
            args += 2;
            nargs -= 2;
            continue;
        } else {
            fprintf(stderr, "Unknown argument %s\n", *args);
            goto err;
        }
    }

    if (!SSL_CONF_CTX_finish(cctx)) {
        fprintf(stderr, "Finish error\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }
#ifdef ITERATE_CERTS
    /*
     * Demo of how to iterate over all certificates in an SSL_CTX structure.
     */
    {
        X509 *x;
        int rv;
        rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST);
        while (rv) {
            X509 *x = SSL_CTX_get0_certificate(ctx);
            X509_NAME_print_ex_fp(stdout, X509_get_subject_name(x), 0,
                                  XN_FLAG_ONELINE);
            printf("\n");
            rv = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT);
        }
        fflush(stdout);
    }
#endif
    /* Setup server side SSL bio */
    ssl_bio = BIO_new_ssl(ctx, 0);

    if ((in = BIO_new_accept(port)) == NULL)
        goto err;

    /*
     * This means that when a new connection is accepted on 'in', The ssl_bio
     * will be 'duplicated' and have the new socket BIO push into it.
     * Basically it means the SSL BIO will be automatically setup
     */
    BIO_set_accept_bios(in, ssl_bio);

 again:
    /*
     * The first call will setup the accept socket, and the second will get a
     * socket.  In this loop, the first actual accept will occur in the
     * BIO_read() function.
     */

    if (BIO_do_accept(in) <= 0)
        goto err;

    for (;;) {
        i = BIO_read(in, buf, 512);
        if (i == 0) {
            /*
             * If we have finished, remove the underlying BIO stack so the
             * next time we call any function for this BIO, it will attempt
             * to do an accept
             */
            printf("Done\n");
            tmp = BIO_pop(in);
            BIO_free_all(tmp);
            goto again;
        }
        if (i < 0)
            goto err;
        fwrite(buf, 1, i, stdout);
        fflush(stdout);
    }

    ret = 0;
 err:
    if (ret) {
        ERR_print_errors_fp(stderr);
    }
    BIO_free(in);
    exit(ret);
    return (!ret);
}
Beispiel #7
0
int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	char **args;
	char *host = NULL, *port = NULL, *path = "/";
	char *reqin = NULL, *respin = NULL;
	char *reqout = NULL, *respout = NULL;
	char *signfile = NULL, *keyfile = NULL;
	char *rsignfile = NULL, *rkeyfile = NULL;
	char *outfile = NULL;
	int add_nonce = 1, noverify = 0, use_ssl = -1;
	OCSP_REQUEST *req = NULL;
	OCSP_RESPONSE *resp = NULL;
	OCSP_BASICRESP *bs = NULL;
	X509 *issuer = NULL, *cert = NULL;
	X509 *signer = NULL, *rsigner = NULL;
	EVP_PKEY *key = NULL, *rkey = NULL;
	BIO *acbio = NULL, *cbio = NULL;
	BIO *derbio = NULL;
	BIO *out = NULL;
	int req_text = 0, resp_text = 0;
	long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
	char *CAfile = NULL, *CApath = NULL;
	X509_STORE *store = NULL;
	SSL_CTX *ctx = NULL;
	STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
	char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
	unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
	int ret = 1;
	int accept_count = -1;
	int badarg = 0;
	int i;
	int ignore_err = 0;
	STACK *reqnames = NULL;
	STACK_OF(OCSP_CERTID) *ids = NULL;

	X509 *rca_cert = NULL;
	char *ridx_filename = NULL;
	char *rca_filename = NULL;
	CA_DB *rdb = NULL;
	int nmin = 0, ndays = -1;

	if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

	if (!load_config(bio_err, NULL))
		goto end;
	SSL_load_error_strings();
	OpenSSL_add_ssl_algorithms();
	args = argv + 1;
	reqnames = sk_new_null();
	ids = sk_OCSP_CERTID_new_null();
	while (!badarg && *args && *args[0] == '-')
		{
		if (!strcmp(*args, "-out"))
			{
			if (args[1])
				{
				args++;
				outfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-url"))
			{
			if (args[1])
				{
				args++;
				if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl))
					{
					BIO_printf(bio_err, "Error parsing URL\n");
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-host"))
			{
			if (args[1])
				{
				args++;
				host = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-port"))
			{
			if (args[1])
				{
				args++;
				port = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-ignore_err"))
			ignore_err = 1;
		else if (!strcmp(*args, "-noverify"))
			noverify = 1;
		else if (!strcmp(*args, "-nonce"))
			add_nonce = 2;
		else if (!strcmp(*args, "-no_nonce"))
			add_nonce = 0;
		else if (!strcmp(*args, "-resp_no_certs"))
			rflags |= OCSP_NOCERTS;
		else if (!strcmp(*args, "-resp_key_id"))
			rflags |= OCSP_RESPID_KEY;
		else if (!strcmp(*args, "-no_certs"))
			sign_flags |= OCSP_NOCERTS;
		else if (!strcmp(*args, "-no_signature_verify"))
			verify_flags |= OCSP_NOSIGS;
		else if (!strcmp(*args, "-no_cert_verify"))
			verify_flags |= OCSP_NOVERIFY;
		else if (!strcmp(*args, "-no_chain"))
			verify_flags |= OCSP_NOCHAIN;
		else if (!strcmp(*args, "-no_cert_checks"))
			verify_flags |= OCSP_NOCHECKS;
		else if (!strcmp(*args, "-no_explicit"))
			verify_flags |= OCSP_NOEXPLICIT;
		else if (!strcmp(*args, "-trust_other"))
			verify_flags |= OCSP_TRUSTOTHER;
		else if (!strcmp(*args, "-no_intern"))
			verify_flags |= OCSP_NOINTERN;
		else if (!strcmp(*args, "-text"))
			{
			req_text = 1;
			resp_text = 1;
			}
		else if (!strcmp(*args, "-req_text"))
			req_text = 1;
		else if (!strcmp(*args, "-resp_text"))
			resp_text = 1;
		else if (!strcmp(*args, "-reqin"))
			{
			if (args[1])
				{
				args++;
				reqin = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-respin"))
			{
			if (args[1])
				{
				args++;
				respin = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-signer"))
			{
			if (args[1])
				{
				args++;
				signfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-VAfile"))
			{
			if (args[1])
				{
				args++;
				verify_certfile = *args;
				verify_flags |= OCSP_TRUSTOTHER;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-sign_other"))
			{
			if (args[1])
				{
				args++;
				sign_certfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-verify_other"))
			{
			if (args[1])
				{
				args++;
				verify_certfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-CAfile"))
			{
			if (args[1])
				{
				args++;
				CAfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-CApath"))
			{
			if (args[1])
				{
				args++;
				CApath = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-validity_period"))
			{
			if (args[1])
				{
				args++;
				nsec = atol(*args);
				if (nsec < 0)
					{
					BIO_printf(bio_err,
						"Illegal validity period %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-status_age"))
			{
			if (args[1])
				{
				args++;
				maxage = atol(*args);
				if (maxage < 0)
					{
					BIO_printf(bio_err,
						"Illegal validity age %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		 else if (!strcmp(*args, "-signkey"))
			{
			if (args[1])
				{
				args++;
				keyfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-reqout"))
			{
			if (args[1])
				{
				args++;
				reqout = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-respout"))
			{
			if (args[1])
				{
				args++;
				respout = *args;
				}
			else badarg = 1;
			}
		 else if (!strcmp(*args, "-path"))
			{
			if (args[1])
				{
				args++;
				path = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-issuer"))
			{
			if (args[1])
				{
				args++;
				X509_free(issuer);
				issuer = load_cert(bio_err, *args, FORMAT_PEM,
					NULL, e, "issuer certificate");
				if(!issuer) goto end;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-cert"))
			{
			if (args[1])
				{
				args++;
				X509_free(cert);
				cert = load_cert(bio_err, *args, FORMAT_PEM,
					NULL, e, "certificate");
				if(!cert) goto end;
				if(!add_ocsp_cert(&req, cert, issuer, ids))
					goto end;
				if(!sk_push(reqnames, *args))
					goto end;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-serial"))
			{
			if (args[1])
				{
				args++;
				if(!add_ocsp_serial(&req, *args, issuer, ids))
					goto end;
				if(!sk_push(reqnames, *args))
					goto end;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-index"))
			{
			if (args[1])
				{
				args++;
				ridx_filename = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-CA"))
			{
			if (args[1])
				{
				args++;
				rca_filename = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-nmin"))
			{
			if (args[1])
				{
				args++;
				nmin = atol(*args);
				if (nmin < 0)
					{
					BIO_printf(bio_err,
						"Illegal update period %s\n",
						*args);
					badarg = 1;
					}
				}
				if (ndays == -1)
					ndays = 0;
			else badarg = 1;
			}
		else if (!strcmp (*args, "-nrequest"))
			{
			if (args[1])
				{
				args++;
				accept_count = atol(*args);
				if (accept_count < 0)
					{
					BIO_printf(bio_err,
						"Illegal accept count %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!strcmp (*args, "-ndays"))
			{
			if (args[1])
				{
				args++;
				ndays = atol(*args);
				if (ndays < 0)
					{
					BIO_printf(bio_err,
						"Illegal update period %s\n",
						*args);
					badarg = 1;
					}
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-rsigner"))
			{
			if (args[1])
				{
				args++;
				rsignfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-rkey"))
			{
			if (args[1])
				{
				args++;
				rkeyfile = *args;
				}
			else badarg = 1;
			}
		else if (!strcmp(*args, "-rother"))
			{
			if (args[1])
				{
				args++;
				rcertfile = *args;
				}
			else badarg = 1;
			}
		else badarg = 1;
		args++;
		}

	/* Have we anything to do? */
	if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1;

	if (badarg)
		{
		BIO_printf (bio_err, "OCSP utility\n");
		BIO_printf (bio_err, "Usage ocsp [options]\n");
		BIO_printf (bio_err, "where options are\n");
		BIO_printf (bio_err, "-out file          output filename\n");
		BIO_printf (bio_err, "-issuer file       issuer certificate\n");
		BIO_printf (bio_err, "-cert file         certificate to check\n");
		BIO_printf (bio_err, "-serial n          serial number to check\n");
		BIO_printf (bio_err, "-signer file       certificate to sign OCSP request with\n");
		BIO_printf (bio_err, "-signkey file      private key to sign OCSP request with\n");
		BIO_printf (bio_err, "-sign_other file   additional certificates to include in signed request\n");
		BIO_printf (bio_err, "-no_certs          don't include any certificates in signed request\n");
		BIO_printf (bio_err, "-req_text          print text form of request\n");
		BIO_printf (bio_err, "-resp_text         print text form of response\n");
		BIO_printf (bio_err, "-text              print text form of request and response\n");
		BIO_printf (bio_err, "-reqout file       write DER encoded OCSP request to \"file\"\n");
		BIO_printf (bio_err, "-respout file      write DER encoded OCSP reponse to \"file\"\n");
		BIO_printf (bio_err, "-reqin file        read DER encoded OCSP request from \"file\"\n");
		BIO_printf (bio_err, "-respin file       read DER encoded OCSP reponse from \"file\"\n");
		BIO_printf (bio_err, "-nonce             add OCSP nonce to request\n");
		BIO_printf (bio_err, "-no_nonce          don't add OCSP nonce to request\n");
		BIO_printf (bio_err, "-url URL           OCSP responder URL\n");
		BIO_printf (bio_err, "-host host:n       send OCSP request to host on port n\n");
		BIO_printf (bio_err, "-path              path to use in OCSP request\n");
		BIO_printf (bio_err, "-CApath dir        trusted certificates directory\n");
		BIO_printf (bio_err, "-CAfile file       trusted certificates file\n");
		BIO_printf (bio_err, "-VAfile file       validator certificates file\n");
		BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n");
		BIO_printf (bio_err, "-status_age n      maximum status age in seconds\n");
		BIO_printf (bio_err, "-noverify          don't verify response at all\n");
		BIO_printf (bio_err, "-verify_other file additional certificates to search for signer\n");
		BIO_printf (bio_err, "-trust_other       don't verify additional certificates\n");
		BIO_printf (bio_err, "-no_intern         don't search certificates contained in response for signer\n");
		BIO_printf (bio_err, "-no_signature_verify don't check signature on response\n");
		BIO_printf (bio_err, "-no_cert_verify    don't check signing certificate\n");
		BIO_printf (bio_err, "-no_chain          don't chain verify response\n");
		BIO_printf (bio_err, "-no_cert_checks    don't do additional checks on signing certificate\n");
		BIO_printf (bio_err, "-port num		 port to run responder on\n");
		BIO_printf (bio_err, "-index file	 certificate status index file\n");
		BIO_printf (bio_err, "-CA file		 CA certificate\n");
		BIO_printf (bio_err, "-rsigner file	 responder certificate to sign responses with\n");
		BIO_printf (bio_err, "-rkey file	 responder key to sign responses with\n");
		BIO_printf (bio_err, "-rother file	 other certificates to include in response\n");
		BIO_printf (bio_err, "-resp_no_certs     don't include any certificates in response\n");
		BIO_printf (bio_err, "-nmin n	 	 number of minutes before next update\n");
		BIO_printf (bio_err, "-ndays n	 	 number of days before next update\n");
		BIO_printf (bio_err, "-resp_key_id       identify reponse by signing certificate key ID\n");
		BIO_printf (bio_err, "-nrequest n        number of requests to accept (default unlimited)\n");
		goto end;
		}

	if(outfile) out = BIO_new_file(outfile, "w");
	else out = BIO_new_fp(stdout, BIO_NOCLOSE);

	if(!out)
		{
		BIO_printf(bio_err, "Error opening output file\n");
		goto end;
		}

	if (!req && (add_nonce != 2)) add_nonce = 0;

	if (!req && reqin)
		{
		derbio = BIO_new_file(reqin, "rb");
		if (!derbio)
			{
			BIO_printf(bio_err, "Error Opening OCSP request file\n");
			goto end;
			}
		req = d2i_OCSP_REQUEST_bio(derbio, NULL);
		BIO_free(derbio);
		if(!req)
			{
			BIO_printf(bio_err, "Error reading OCSP request\n");
			goto end;
			}
		}

	if (!req && port)
		{
		acbio = init_responder(port);
		if (!acbio)
			goto end;
		}

	if (rsignfile && !rdb)
		{
		if (!rkeyfile) rkeyfile = rsignfile;
		rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
			NULL, e, "responder certificate");
		if (!rsigner)
			{
			BIO_printf(bio_err, "Error loading responder certificate\n");
			goto end;
			}
		rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
			NULL, e, "CA certificate");
		if (rcertfile)
			{
			rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
				NULL, e, "responder other certificates");
			if (!rother) goto end;
			}
		rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
			"responder private key");
		if (!rkey)
			goto end;
		}
	if(acbio)
		BIO_printf(bio_err, "Waiting for OCSP client connections...\n");

	redo_accept:

	if (acbio)
		{
		if (!do_responder(&req, &cbio, acbio, port))
			goto end;
		if (!req)
			{
			resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
			send_ocsp_response(cbio, resp);
			goto done_resp;
			}
		}

	if (!req && (signfile || reqout || host || add_nonce || ridx_filename))
		{
		BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
		goto end;
		}

	if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1);

	if (signfile)
		{
		if (!keyfile) keyfile = signfile;
		signer = load_cert(bio_err, signfile, FORMAT_PEM,
			NULL, e, "signer certificate");
		if (!signer)
			{
			BIO_printf(bio_err, "Error loading signer certificate\n");
			goto end;
			}
		if (sign_certfile)
			{
			sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
				NULL, e, "signer certificates");
			if (!sign_other) goto end;
			}
		key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
			"signer private key");
		if (!key)
			goto end;
		if (!OCSP_request_sign(req, signer, key, EVP_sha1(), sign_other, sign_flags))
			{
			BIO_printf(bio_err, "Error signing OCSP request\n");
			goto end;
			}
		}

	if (req_text && req) OCSP_REQUEST_print(out, req, 0);

	if (reqout)
		{
		derbio = BIO_new_file(reqout, "wb");
		if(!derbio)
			{
			BIO_printf(bio_err, "Error opening file %s\n", reqout);
			goto end;
			}
		i2d_OCSP_REQUEST_bio(derbio, req);
		BIO_free(derbio);
		}

	if (ridx_filename && (!rkey || !rsigner || !rca_cert))
		{
		BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n");
		goto end;
		}

	if (ridx_filename && !rdb)
		{
		rdb = load_index(ridx_filename, NULL);
		if (!rdb) goto end;
		if (!index_index(rdb)) goto end;
		}

	if (rdb)
		{
		i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays);
		if (cbio)
			send_ocsp_response(cbio, resp);
		}
	else if (host)
		{
#ifndef OPENSSL_NO_SOCK
		cbio = BIO_new_connect(host);
#else
		BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n");
		goto end;
#endif
		if (!cbio)
			{
			BIO_printf(bio_err, "Error creating connect BIO\n");
			goto end;
			}
		if (port) BIO_set_conn_port(cbio, port);
		if (use_ssl == 1)
			{
			BIO *sbio;
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
			ctx = SSL_CTX_new(SSLv23_client_method());
#elif !defined(OPENSSL_NO_SSL3)
			ctx = SSL_CTX_new(SSLv3_client_method());
#elif !defined(OPENSSL_NO_SSL2)
			ctx = SSL_CTX_new(SSLv2_client_method());
#else
			BIO_printf(bio_err, "SSL is disabled\n");
			goto end;
#endif
			if (ctx == NULL)
				{
				BIO_printf(bio_err, "Error creating SSL context.\n");
				goto end;
				}
			SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
			sbio = BIO_new_ssl(ctx, 1);
			cbio = BIO_push(sbio, cbio);
			}
		if (BIO_do_connect(cbio) <= 0)
			{
			BIO_printf(bio_err, "Error connecting BIO\n");
			goto end;
			}
		resp = OCSP_sendreq_bio(cbio, path, req);
		BIO_free_all(cbio);
		cbio = NULL;
		if (!resp)
			{
			BIO_printf(bio_err, "Error querying OCSP responsder\n");
			goto end;
			}
		}
	else if (respin)
		{
		derbio = BIO_new_file(respin, "rb");
		if (!derbio)
			{
			BIO_printf(bio_err, "Error Opening OCSP response file\n");
			goto end;
			}
		resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
		BIO_free(derbio);
		if(!resp)
			{
			BIO_printf(bio_err, "Error reading OCSP response\n");
			goto end;
			}
	
		}
	else
		{
		ret = 0;
		goto end;
		}

	done_resp:

	if (respout)
		{
		derbio = BIO_new_file(respout, "wb");
		if(!derbio)
			{
			BIO_printf(bio_err, "Error opening file %s\n", respout);
			goto end;
			}
		i2d_OCSP_RESPONSE_bio(derbio, resp);
		BIO_free(derbio);
		}

	i = OCSP_response_status(resp);

	if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL)
		{
		BIO_printf(out, "Responder Error: %s (%d)\n",
				OCSP_response_status_str(i), i);
		if (ignore_err)
			goto redo_accept;
		ret = 0;
		goto end;
		}

	if (resp_text) OCSP_RESPONSE_print(out, resp, 0);

	/* If running as responder don't verify our own response */
	if (cbio)
		{
		if (accept_count > 0)
			accept_count--;
		/* Redo if more connections needed */
		if (accept_count)
			{
			BIO_free_all(cbio);
			cbio = NULL;
			OCSP_REQUEST_free(req);
			req = NULL;
			OCSP_RESPONSE_free(resp);
			resp = NULL;
			goto redo_accept;
			}
		goto end;
		}

	if (!store)
		store = setup_verify(bio_err, CAfile, CApath);
	if (!store)
		goto end;
	if (verify_certfile)
		{
		verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
			NULL, e, "validator certificate");
		if (!verify_other) goto end;
		}

	bs = OCSP_response_get1_basic(resp);

	if (!bs)
		{
		BIO_printf(bio_err, "Error parsing response\n");
		goto end;
		}

	if (!noverify)
		{
		if (req && ((i = OCSP_check_nonce(req, bs)) <= 0))
			{
			if (i == -1)
				BIO_printf(bio_err, "WARNING: no nonce in response\n");
			else
				{
				BIO_printf(bio_err, "Nonce Verify error\n");
				goto end;
				}
			}

		i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
                if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0);

		if(i <= 0)
			{
			BIO_printf(bio_err, "Response Verify Failure\n");
			ERR_print_errors(bio_err);
			}
		else
			BIO_printf(bio_err, "Response verify OK\n");

		}

	if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
		goto end;

	ret = 0;

end:
	ERR_print_errors(bio_err);
	X509_free(signer);
	X509_STORE_free(store);
	EVP_PKEY_free(key);
	EVP_PKEY_free(rkey);
	X509_free(issuer);
	X509_free(cert);
	X509_free(rsigner);
	X509_free(rca_cert);
	free_index(rdb);
	BIO_free_all(cbio);
	BIO_free_all(acbio);
	BIO_free(out);
	OCSP_REQUEST_free(req);
	OCSP_RESPONSE_free(resp);
	OCSP_BASICRESP_free(bs);
	sk_free(reqnames);
	sk_OCSP_CERTID_free(ids);
	sk_X509_pop_free(sign_other, X509_free);
	sk_X509_pop_free(verify_other, X509_free);

	if (use_ssl != -1)
		{
		OPENSSL_free(host);
		OPENSSL_free(port);
		OPENSSL_free(path);
		SSL_CTX_free(ctx);
		}

	OPENSSL_EXIT(ret);
}
Beispiel #8
0
//--------------------------------------------------
// sends an OCSP_REQUES object to remore server and
// retrieves the OCSP_RESPONSE object
// resp - buffer to store the new responses pointer
// req - request objects pointer
// url - OCSP responder URL
//--------------------------------------------------
int ddocPullUrl(const char* url, DigiDocMemBuf* pSendData, DigiDocMemBuf* pRecvData,
                const char* proxyHost, const char* proxyPort)
{
    BIO* cbio = 0, *sbio = 0;
    SSL_CTX *ctx = NULL;
    char *host = NULL, *port = NULL, *path = "/", buf[200];
    int err = ERR_OK, use_ssl = -1, rc;
    long e;

    //RETURN_IF_NULL_PARAM(pSendData); // may be null if nothing to send?
    RETURN_IF_NULL_PARAM(pRecvData);
    RETURN_IF_NULL_PARAM(url);

    ddocDebug(4, "ddocPullUrl", "URL: %s, in: %d bytes", url, pSendData->nLen);
    //there is an HTTP proxy - connect to that instead of the target host
    if (proxyHost != 0 && *proxyHost != '\0') {
        host = (char*)proxyHost;
        if(proxyPort != 0 && *proxyPort != '\0')
            port = (char*)proxyPort;
        path = (char*)url;
    } else {
        if(OCSP_parse_url((char*)url, &host, &port, &path, &use_ssl) == 0) {
            ddocDebug(1, "ddocPullUrl", "Failed to parse the URL");
            return ERR_WRONG_URL_OR_PROXY;
        }
    }

    if((cbio = BIO_new_connect(host)) != 0) {
        ddocDebug(4, "ddocPullUrl", "Host: %s port: %s", host, port);
        if(port != NULL) {
            BIO_set_conn_port(cbio, port);
        }
        if(use_ssl == 1) {
            ctx = SSL_CTX_new(SSLv23_client_method());
            SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
            sbio = BIO_new_ssl(ctx, 1);
            cbio = BIO_push(sbio, cbio);
        }
        if ((rc = BIO_do_connect(cbio)) > 0) {
            ddocDebug(4, "ddocPullUrl", "Connected: %d", rc);
            if(pSendData && pSendData->nLen && pSendData->pMem) {
                rc = BIO_write(cbio, pSendData->pMem, pSendData->nLen);
                ddocDebug(4, "ddocPullUrl", "Sent: %d bytes, got: %d", pSendData->nLen, rc);
            }
            do {
                memset(buf, 0, sizeof(buf));
                rc = BIO_read(cbio, buf, sizeof(buf)-1);
                ddocDebug(4, "ddocPullUrl", "Received: %d bytes\n", rc);
                if(rc > 0)
                    err = ddocMemAppendData(pRecvData, buf, rc);
            } while(rc > 0);
            ddocDebug(4, "ddocPullUrl", "Total received: %d bytes\n", pRecvData->nLen);
        } else {
            //if no connection
            e = checkErrors();
            if(ERR_GET_REASON(e) == BIO_R_BAD_HOSTNAME_LOOKUP ||
                    ERR_GET_REASON(e) == OCSP_R_SERVER_WRITE_ERROR)
                err = ERR_CONNECTION_FAILURE;
            else
                err = (host != NULL) ? ERR_WRONG_URL_OR_PROXY : ERR_CONNECTION_FAILURE;
        }
        BIO_free_all(cbio);
        if (use_ssl != -1) {
            OPENSSL_free(host);
            OPENSSL_free(port);
            OPENSSL_free(path);
            SSL_CTX_free(ctx);
        }
    }
    else
        err = ERR_CONNECTION_FAILURE;
    return(err);
}
Beispiel #9
0
int main(int argc, char **argv)
{
  char buf[BUFFER_SIZE];

  SSL_CTX *ctx;
  const SSL_METHOD *method;
  BIO *abio, *cbio;

  if (argc < 2) {
    fprintf(stderr, "Usage: %s [port]\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  // init openssl lib.
  SSL_library_init(); // call OpenSSL_add_ssl_algorithms();
  ERR_load_BIO_strings();
  SSL_load_error_strings();

  // setup tls context.
  method = TLSv1_2_server_method(); // SSLv23_server_method();
  ctx = SSL_CTX_new(method);
  if (!ctx) {
    perror("Unable to create SSL context");
    ERR_print_errors_fp(stderr);
    exit(EXIT_FAILURE);
  }
  /* Set the key and cert */
  if (SSL_CTX_use_certificate_file(ctx, CERT_FILE_PATH, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(EXIT_FAILURE);
  }
  if (SSL_CTX_use_PrivateKey_file(ctx, KEY_FILE_PATH, SSL_FILETYPE_PEM) <= 0 ) {
    ERR_print_errors_fp(stderr);
    exit(EXIT_FAILURE);
  }
  SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES256-GCM-SHA384");
  SSL_CTX_set_ecdh_auto(ctx, 1);

  // create BIO(high level API); for accept
  abio = BIO_new_accept(argv[1]);
  if(BIO_do_accept(abio) <= 0) {
    // first BIO_do_accept() is as to init BIO.
    fprintf(stderr, "Error setting up accept\n");
    ERR_print_errors_fp(stderr);
    exit(0);
  }
  // configuration for I/O operation over ssl/tls.
  BIO_set_accept_bios(abio, BIO_new_ssl(ctx, 0));

  // listen loop
  printf("Server is listening on %d\n", atoi(argv[1]));
  while (1) {
    if(BIO_do_accept(abio) <= 0) {
      fprintf(stderr, "Error accepting connection\n");
      ERR_print_errors_fp(stderr);
      exit(0);
    }
    fprintf(stderr, "Connection 1 established\n");
    /* Retrieve BIO for connection */
    cbio = BIO_pop(abio);
    while (1) {
      int len, err;
      len = BIO_read(cbio, buf, BUFFER_SIZE);
      if (!len) break;
      if (len < 0) {
        fprintf(stderr, "error SSL_read");
        break;
      }
      err = BIO_write(cbio, buf, len);
      if (err < 0) {
        fprintf(stderr, "error SSL_write");
        break;
      }
    }
    BIO_free(cbio);
  }
}
Beispiel #10
0
int main(int argc, char *argv[])
{
    char *port = NULL;
    BIO *ssl_bio, *tmp;
    SSL_CTX *ctx;
    char buf[512];
    int ret = 1, i;

    if (argc <= 1)
        port = "*:4433";
    else
        port = argv[1];

    signal(SIGINT, close_up);

    SSL_load_error_strings();

    /* Add ciphers and message digests */
    OpenSSL_add_ssl_algorithms();

    ctx = SSL_CTX_new(TLS_server_method());
    if (!SSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
        goto err;
    if (!SSL_CTX_use_PrivateKey_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
        goto err;
    if (!SSL_CTX_check_private_key(ctx))
        goto err;

    /* Setup server side SSL bio */
    ssl_bio = BIO_new_ssl(ctx, 0);

    if ((in = BIO_new_accept(port)) == NULL)
        goto err;

    /*
     * This means that when a new connection is accepted on 'in', The ssl_bio
     * will be 'duplicated' and have the new socket BIO push into it.
     * Basically it means the SSL BIO will be automatically setup
     */
    BIO_set_accept_bios(in, ssl_bio);

again:
    /*
     * The first call will setup the accept socket, and the second will get a
     * socket.  In this loop, the first actual accept will occur in the
     * BIO_read() function.
     */

    if (BIO_do_accept(in) <= 0)
        goto err;

    for (;;) {
        i = BIO_read(in, buf, 512);
        if (i == 0) {
            /*
             * If we have finished, remove the underlying BIO stack so the
             * next time we call any function for this BIO, it will attempt
             * to do an accept
             */
            printf("Done\n");
            tmp = BIO_pop(in);
            BIO_free_all(tmp);
            goto again;
        }
        if (i < 0)
            goto err;
        fwrite(buf, 1, i, stdout);
        fflush(stdout);
    }

    ret = 0;
err:
    if (ret) {
        ERR_print_errors_fp(stderr);
    }
    BIO_free(in);
    exit(ret);
    return (!ret);
}
Beispiel #11
0
int main(int argc, char *argv[])
{
	SSL *ssl;
	SSL_CTX *ctx;
	BIO *bio, *abio, *cbio;
	pthread_t t;
	X509 *peer;
	int (*callback)(char *, int, int, void *) = &password_callback;

	SSL_library_init();

	SSL_load_error_strings();
	ERR_load_BIO_strings();
	ERR_load_SSL_strings();

	printf("Attempting to create SSL context...\n");
	ctx = SSL_CTX_new(SSLv3_server_method());
	if(ctx == NULL) {
		printf("Failed. Aborting.\n");
		ERR_print_errors_fp(stdout);
		return 0;
	}

	printf("Loading certificates...\n");
	SSL_CTX_set_default_passwd_cb(ctx, callback);
	//if (SSL_CTX_use_certificate_file(ctx, "./CA/server_cert.pem", SSL_FILETYPE_PEM) != 1) {
	if (SSL_CTX_use_certificate_chain_file(ctx, "./CAtest/server_cert.pem") != 1) {
		/* Handle failed load here */
		ERR_print_errors_fp(stdout);
		exit(1);
	}
	if (SSL_CTX_use_PrivateKey_file(ctx, "./CAtest/private/server_key.pem", SSL_FILETYPE_PEM) != 1) {
		/* Handle failed load here */
		ERR_print_errors_fp(stdout);
		exit(1);
	}
	if (!SSL_CTX_load_verify_locations(ctx, "./CAtest/cacert.pem", "./CA/")) {
		/* Handle failed load here */
        ERR_print_errors_fp(stdout);
		exit(1);
	}

	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, verify_callback);
	SSL_CTX_set_verify_depth(ctx, 5);

	printf("Attempting to create BIO object...\n");
	bio = BIO_new_ssl(ctx, 0);
	if(bio == NULL) {
		printf("Failed. Aborting.\n");
		ERR_print_errors_fp(stdout);
		SSL_CTX_free(ctx);
		return 0;
	}

	printf("Attempting to set up BIO for SSL...\n");
	BIO_get_ssl(bio, &ssl);
	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

	abio = BIO_new_accept("4422");
	BIO_set_accept_bios(abio, bio);

	/* First call to BIO_accept() sets up accept BIO */
	if (BIO_do_accept(abio) <= 0) {
		fprintf(stderr, "Error setting up accept\n");
		ERR_print_errors_fp(stderr);
		exit(0);
	}

	do {
		/* Wait for incoming connection */
		if (BIO_do_accept(abio) <= 0) {
			fprintf(stderr, "Error accepting connection\n");
			ERR_print_errors_fp(stderr);
			exit(0);
		}

		fprintf(stderr, "Connection 1 established\n");
		/* Retrieve BIO for connection */
		cbio = BIO_pop(abio);
		pthread_create(&t, NULL, handle_connection, cbio);
	} while (1);

	SSL_shutdown(ssl);
	BIO_free_all(bio);
	BIO_free_all(abio);
	SSL_CTX_free(ctx);
	SSL_free(ssl);

	return 0;
}
Beispiel #12
0
Datei: pop.c Projekt: kusune/from
POP_SESSION *pop_set_socket(POP_SESSION *psp, int s, int opt)
{
    if (s < 0) {
	return NULL;
    }

    if (psp == NULL && (psp = pop_session_create()) == NULL) {
	return NULL;
    }

#ifdef WITH_OPENSSL
    if ((psp->bio = BIO_new_socket(s, BIO_NOCLOSE)) == NULL) {
	__pop_set_error_openssl(psp, "BIO_new_socket(): ");
	pop_session_destroy(psp);
	return NULL;
    }

#ifdef ENABLE_SSL
    if (opt & POP_OPT_SSL) {
	SSL_CTX *ctxp;
	BIO *bio_ssl;

	if ((ctxp = SSL_CTX_new(SSLv23_client_method())) == NULL) {
	    __pop_set_error_openssl(psp, "SSL_CTX_new(): ");
	    pop_session_destroy(psp);
	    return NULL;
	}
	if ((bio_ssl = BIO_new_ssl(ctxp, 1)) == NULL) {
	    __pop_set_error_openssl(psp, "BIO_new_ssl(): ");
	    pop_session_destroy(psp);
	    return NULL;
	}
	BIO_push(bio_ssl, psp->bio);
	psp->bio = bio_ssl;
	BIO_do_handshake(psp->bio);
    }
#endif /* ENABLE_SSL */

    {
	BIO *bio_buffer;

	if ((bio_buffer = BIO_new(BIO_f_buffer())) == NULL) {
	    __pop_set_error_openssl(psp, "BIO_new(): ");
	    pop_session_destroy(psp);
	    return NULL;
	}
	BIO_push(bio_buffer, psp->bio);
	psp->bio = bio_buffer;
    }
#else /* WITH_OPENSSL */
    if ((psp->sw = dup(s)) < 0) {
	__pop_set_error_errno(psp, "dup(s): ");
	pop_session_destroy(psp);
	return NULL;
    }
    if ((psp->fw = fdopen(psp->sw, "w")) == NULL) {
	__pop_set_error_errno(psp, "fdopen(fw): ");
	pop_session_destroy(psp);
	return NULL;
    }
    if ((psp->fr = fdopen(s, "r")) == NULL) {
	__pop_set_error_errno(psp, "fdopen(fr): ");
	pop_session_destroy(psp);
	return NULL;
    }
    psp->sr = s;
#endif /* WITH_OPENSSL */

    return psp;
}
Beispiel #13
0
int main(){
  int len = 1024; //buffer length
  char buf[len]; //read buffer
  
  /* Initializing OpenSSL */
  SSL_load_error_strings();
  ERR_load_BIO_strings();
  OpenSSL_add_all_algorithms();
  SSL_library_init();

  BIO *bio, *abio, *out; //the sockets
  SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
  SSL *ssl;

  if( ctx == NULL ){
    fprintf(stderr, "DEBUG ctx is null\n");
    fprintf(stderr, "ERROR::OpenSLL: %s\n", ERR_reason_error_string(ERR_get_error()));
    exit(1);
  }
  
  //get password for private key
  //  SSL_CTX_set_default_passwd_cb( ctx, &pem_passwd_cb );

  //load certificate (with public key)
  SSL_CTX_use_certificate_file( ctx, "/home/mml/Develop/ca/certs/01.pem", SSL_FILETYPE_PEM);
  //load private key
  SSL_CTX_use_PrivateKey_file( ctx, "/home/mml/Develop/ca/testkey.pem", SSL_FILETYPE_PEM);

  bio = BIO_new_ssl(ctx, 0);
  if( bio == NULL ){
    fprintf(stderr, "ERROR cannot bind\n");
    exit(1);
  }

  BIO_get_ssl(bio, &ssl);
  SSL_set_mode( ssl, SSL_MODE_AUTO_RETRY );

  abio = BIO_new_accept("localhost:15001");
  BIO_set_accept_bios(abio, bio);

  BIO_do_accept(abio);

  fprintf(stdout, "DEBUG: waiting for connection\n");
  BIO_do_accept(abio);

  out = BIO_pop(abio);

  fprintf(stdout, "DEBUG: doing handshake\n");
  BIO_do_handshake(out);
  
  if(BIO_write(out, "Hello", 5) <= 0){
    if(! BIO_should_retry(bio)) {
      fprintf(stderr, "ERROR connection is already closed. (write)\n");
      exit(1);
    } else {
      //retry routine
    }
  }
  
  bzero(buf, len); 
  if( BIO_read(out, buf, len) <= 0 ){
    if( !(BIO_should_retry(bio)) ){
      fprintf(stderr, "ERROR connection is already closed (read)\n");
      exit(0);
      
    } else {
      //retry routine
    }
  }

  fprintf(stdout, "Hello%s\n", buf);

  //close connection
  BIO_free_all(abio);
  BIO_free_all(out);
  BIO_free_all(bio);
  SSL_CTX_free(ctx);
  
  return 0;
}
Beispiel #14
0
static int
openssl_connect(BroConn *bc)
{
  int flags, sockfd = -1;
  BIO *bio = NULL;
  BIO *ssl_bio = NULL;

  D_ENTER;

  if (! bc || ! bc->peer || ! *(bc->peer))
    D_RETURN_(FALSE);
  
  /* Make sure OpenSSL is initialised -- this has effect only once */
  if (! __bro_openssl_init())
    D_RETURN_(FALSE);

	/* Use socket provided by user if BroConn came via bro_conn_new_socket */
	if ( bc->socket >= 0 )
		{
		D(("Connection created from externally provided socket.\n"));
		sockfd = bc->socket;
		}
	else
		sockfd = try_connect(bc->peer);

	if ( sockfd == -1 )
		{
		D(("Error connecting to %s.\n", bc->peer));
		goto err_return;
		}

	if ( ! (bio = BIO_new_socket(sockfd, BIO_CLOSE)) )
		{
		D(("Error creating connection BIO from socket.\n"));
		goto err_return;
		}

	if ( (flags = fcntl(sockfd, F_GETFL, 0)) < 0 )
		{
		D(("Error getting socket flags.\n"));
		goto err_return;
		}

	if ( fcntl(sockfd, F_SETFL, flags|O_NONBLOCK) < 0 )
		{
		D(("Error setting socket to non-blocking.\n"));
		goto err_return;
		}

	/* Don't know whether this is needed but it does not hurt either. 
	 * It is however not sufficient to just call this; we manually need to
	 * set the socket to non-blocking as done above. */
	BIO_set_nbio(bio, 1);

	/* Add SSL if available */
	if ( ctx )
		{
		if ( ! (ssl_bio = BIO_new_ssl(ctx, 1)) )
			{
			D(("Error creating ssl BIO.\n"));
			goto err_return;
			}
		BIO_set_close(ssl_bio, BIO_CLOSE);
		BIO_push(ssl_bio, bio);
		bio = ssl_bio;
		}

	bc->bio = bio;
	D(("Connection established successfully.\n"));
	D_RETURN_(TRUE);

 err_return:

  print_errors();

#ifdef BRO_DEBUG
  if (ctx)
    D(("--- SSL CONNECTION SETUP FAILED. ---"));
  else
    D(("--- CLEARTEXT CONNECTION SETUP FAILED. ---"));
#endif  

  if (bio)
    BIO_free_all(bio);
  
  bc->state->rx_dead = bc->state->tx_dead = TRUE;
  bc->bio = NULL;
  D_RETURN_(FALSE);
}