示例#1
0
// Minimal TLS server. This is largely based on the example at
// https://wiki.openssl.org/index.php/Simple_TLS_Server and the gRPC core
// internals in src/core/lib/tsi/ssl_transport_security.c.
static void server_thread(void *arg) {
  const server_args *args = (server_args *)arg;

  SSL_load_error_strings();
  OpenSSL_add_ssl_algorithms();

  const SSL_METHOD *method = TLSv1_2_server_method();
  SSL_CTX *ctx = SSL_CTX_new(method);
  if (!ctx) {
    perror("Unable to create SSL context");
    ERR_print_errors_fp(stderr);
    abort();
  }

  // Load key pair.
  if (SSL_CTX_use_certificate_file(ctx, SSL_CERT_PATH, SSL_FILETYPE_PEM) < 0) {
    ERR_print_errors_fp(stderr);
    abort();
  }
  if (SSL_CTX_use_PrivateKey_file(ctx, SSL_KEY_PATH, SSL_FILETYPE_PEM) < 0) {
    ERR_print_errors_fp(stderr);
    abort();
  }

  // Set the cipher list to match the one expressed in
  // src/core/lib/tsi/ssl_transport_security.c.
  const char *cipher_list =
      "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-"
      "SHA384:ECDHE-RSA-AES256-GCM-SHA384";
  if (!SSL_CTX_set_cipher_list(ctx, cipher_list)) {
    ERR_print_errors_fp(stderr);
    gpr_log(GPR_ERROR, "Couldn't set server cipher list.");
    abort();
  }

  // Register the ALPN selection callback.
  SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb, args->alpn_preferred);

  // bind/listen/accept at TCP layer.
  const int sock = args->socket;
  gpr_log(GPR_INFO, "Server listening");
  struct sockaddr_in addr;
  socklen_t len = sizeof(addr);
  const int client = accept(sock, (struct sockaddr *)&addr, &len);
  if (client < 0) {
    perror("Unable to accept");
    abort();
  }

  // Establish a SSL* and accept at SSL layer.
  SSL *ssl = SSL_new(ctx);
  GPR_ASSERT(ssl);
  SSL_set_fd(ssl, client);
  if (SSL_accept(ssl) <= 0) {
    ERR_print_errors_fp(stderr);
    gpr_log(GPR_ERROR, "Handshake failed.");
  } else {
    gpr_log(GPR_INFO, "Handshake successful.");
  }

  // Wait until the client drops its connection.
  char buf;
  while (SSL_read(ssl, &buf, sizeof(buf)) > 0)
    ;

  SSL_free(ssl);
  close(client);
  close(sock);
  SSL_CTX_free(ctx);
  EVP_cleanup();
}
示例#2
0
rdpRsaKey* key_new(const char* keyfile)
{
	FILE* fp;
	RSA* rsa;
	rdpRsaKey* key;

	key = (rdpRsaKey*) malloc(sizeof(rdpRsaKey));
	ZeroMemory(key, sizeof(rdpRsaKey));

	if (key == NULL)
		return NULL;

	fp = fopen(keyfile, "r");

	if (fp == NULL)
	{
		fprintf(stderr, "unable to load RSA key from %s: %s.", keyfile, strerror(errno));
		free(key) ;
		return NULL;
	}

	rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);

	if (rsa == NULL)
	{
		ERR_print_errors_fp(stdout);
		fclose(fp);
		free(key) ;
		return NULL;
	}

	fclose(fp);

	switch (RSA_check_key(rsa))
	{
		case 0:
			RSA_free(rsa);
			fprintf(stderr, "invalid RSA key in %s", keyfile);
			free(key) ;
			return NULL;

		case 1:
			/* Valid key. */
			break;

		default:
			ERR_print_errors_fp(stderr);
			RSA_free(rsa);
			free(key) ;
			return NULL;
	}

	if (BN_num_bytes(rsa->e) > 4)
	{
		RSA_free(rsa);
		fprintf(stderr, "RSA public exponent too large in %s", keyfile);
		free(key) ;
		return NULL;
	}

	key->ModulusLength = BN_num_bytes(rsa->n);
	key->Modulus = (BYTE*) malloc(key->ModulusLength);
	BN_bn2bin(rsa->n, key->Modulus);
	crypto_reverse(key->Modulus, key->ModulusLength);

	key->PrivateExponentLength = BN_num_bytes(rsa->d);
	key->PrivateExponent = (BYTE*) malloc(key->PrivateExponentLength);
	BN_bn2bin(rsa->d, key->PrivateExponent);
	crypto_reverse(key->PrivateExponent, key->PrivateExponentLength);

	memset(key->exponent, 0, sizeof(key->exponent));
	BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e));
	crypto_reverse(key->exponent, sizeof(key->exponent));

	RSA_free(rsa);

	return key;
}
示例#3
0
int main(int argc, char *argv[]) {
	
	FILE		*fin, *fkey;
	u_int16_t	siglen;
	u_int32_t	magic;
	long		nread, ndata;
	char		*sigbuf, *inbuf;
	EVP_PKEY	*pkey;
	EVP_MD_CTX	ctx;
	int			err, retval;
	
	if (argc != 3)
		usage();
	
	ERR_load_crypto_strings();
	
	/* open file and check for magic */
	fin = fopen(argv[2], "r+");
	if (fin == NULL) {
		fprintf(stderr, "unable to open file '%s'\n", argv[2]);
		exit(4);
	}
	
	fseek(fin, -(sizeof(magic)), SEEK_END);
	fread(&magic, sizeof(magic), 1, fin);
		
	if (magic != SIG_MAGIC) {
		fclose(fin);
		exit(2);
	}
	
	/* magic is good; get signature length */	
	fseek(fin, -(sizeof(magic) + sizeof(siglen)), SEEK_END);	
	fread(&siglen, sizeof(siglen), 1, fin);
	
	/* read public key */
	fkey = fopen(argv[1], "r");
	if (fkey == NULL) {
		fprintf(stderr, "unable to open public key file '%s'\n", argv[1]);
		exit(4);
	}
	
	pkey = PEM_read_PUBKEY(fkey, NULL, NULL, NULL);
	fclose(fkey);
	
	if (pkey == NULL) {
		ERR_print_errors_fp(stderr);
		exit(4);
	}
	
	/* check if siglen is sane */
	if ((siglen == 0) || (siglen > EVP_PKEY_size(pkey)))
		exit(3);
	
	/* got signature length; read signature */
	sigbuf = malloc(siglen);
	if (sigbuf == NULL)
		exit(4);
	
	fseek(fin, -(sizeof(magic) + sizeof(siglen) + siglen), SEEK_END);	
	if (fread(sigbuf, 1, siglen, fin) != siglen)
		exit(4);
	
	/* signature read; truncate file to remove sig */
	fseek(fin, 0, SEEK_END);
	ndata = ftell(fin) - (sizeof(magic) + sizeof(siglen) + siglen);
	ftruncate(fileno(fin), ndata);
	
	/* verify the signature now */
	EVP_VerifyInit(&ctx, EVP_sha1());
	
	/* allocate data buffer */
	inbuf = malloc(SIG_INBUFLEN);
	if (inbuf == NULL)
		exit(4);
	
	rewind(fin);
	while (!feof(fin)) {
		nread = fread(inbuf, 1, SIG_INBUFLEN, fin);
		if (nread != SIG_INBUFLEN) {
			if (ferror(fin)) {
				fprintf(stderr, "read error in file '%s'\n", argv[2]);
				exit(4);
			}
		}
		
		EVP_VerifyUpdate(&ctx, inbuf, nread);
	}
	
	err = EVP_VerifyFinal(&ctx, sigbuf, siglen, pkey);
	EVP_PKEY_free(pkey);
	
	if (err == 1)
		retval = 0;		/* correct signature */
	else if (err == 0)
		retval = 1;		/* invalid signature */
	else
		retval = 3;		/* error */
	
	free(inbuf);
	free(sigbuf);
	fclose(fin);
	
	return retval;
}
示例#4
0
SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const string &certchainfile):
	pCtx (NULL),
	PrivateKey (NULL),
	Certificate (NULL)
{
	/* TODO: the usage of the specified private-key and cert-chain filenames only applies to
	 * client-side connections at this point. Server connections currently use the default materials.
	 * That needs to be fixed asap.
	 * Also, in this implementation, server-side connections use statically defined X-509 defaults.
	 * One thing I'm really not clear on is whether or not you have to explicitly free X509 and EVP_PKEY
	 * objects when we call our destructor, or whether just calling SSL_CTX_free is enough.
	 */

	if (!bLibraryInitialized) {
		bLibraryInitialized = true;
		SSL_library_init();
		OpenSSL_add_ssl_algorithms();
	        OpenSSL_add_all_algorithms();
		SSL_load_error_strings();
		ERR_load_crypto_strings();

		InitializeDefaultCredentials();
	}

	bIsServer = is_server;
	pCtx = SSL_CTX_new (is_server ? SSLv23_server_method() : SSLv23_client_method());
	if (!pCtx)
		throw std::runtime_error ("no SSL context");

	SSL_CTX_set_options (pCtx, SSL_OP_ALL);
	//SSL_CTX_set_options (pCtx, (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3));

	if (is_server) {
		// The SSL_CTX calls here do NOT allocate memory.
		int e;
		if (privkeyfile.length() > 0)
			e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM);
		else
			e = SSL_CTX_use_PrivateKey (pCtx, DefaultPrivateKey);
		if (e <= 0) ERR_print_errors_fp(stderr);
		assert (e > 0);

		if (certchainfile.length() > 0)
			e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str());
		else
			e = SSL_CTX_use_certificate (pCtx, DefaultCertificate);
		if (e <= 0) ERR_print_errors_fp(stderr);
		assert (e > 0);
	}

	SSL_CTX_set_cipher_list (pCtx, "ALL:!ADH:!LOW:!EXP:!DES-CBC3-SHA:@STRENGTH");

	if (is_server) {
		SSL_CTX_sess_set_cache_size (pCtx, 128);
		SSL_CTX_set_session_id_context (pCtx, (unsigned char*)"eventmachine", 12);
	}
	else {
		int e;
		if (privkeyfile.length() > 0) {
			e = SSL_CTX_use_PrivateKey_file (pCtx, privkeyfile.c_str(), SSL_FILETYPE_PEM);
			if (e <= 0) ERR_print_errors_fp(stderr);
			assert (e > 0);
		}
		if (certchainfile.length() > 0) {
			e = SSL_CTX_use_certificate_chain_file (pCtx, certchainfile.c_str());
			if (e <= 0) ERR_print_errors_fp(stderr);
			assert (e > 0);
		}
	}
}
示例#5
0
int main(int argc, char *argv[])
	{
	BN_CTX *ctx;
	BIO *out;
	char *outfile=NULL;

	results = 0;

	RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */

	argc--;
	argv++;
	while (argc >= 1)
		{
		if (strcmp(*argv,"-results") == 0)
			results=1;
		else if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) break;
			outfile= *(++argv);
			}
		argc--;
		argv++;
		}


	ctx=BN_CTX_new();
	if (ctx == NULL) EXIT(1);

	out=BIO_new(BIO_s_file());
	if (out == NULL) EXIT(1);
	if (outfile == NULL)
		{
		BIO_set_fp(out,stdout,BIO_NOCLOSE);
		}
	else
		{
		if (!BIO_write_filename(out,outfile))
			{
			perror(outfile);
			EXIT(1);
			}
		}

	if (!results)
		BIO_puts(out,"obase=16\nibase=16\n");

	message(out,"BN_add");
	if (!test_add(out)) goto err;
	BIO_flush(out);

	message(out,"BN_sub");
	if (!test_sub(out)) goto err;
	BIO_flush(out);

	message(out,"BN_lshift1");
	if (!test_lshift1(out)) goto err;
	BIO_flush(out);

	message(out,"BN_lshift (fixed)");
	if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
	    goto err;
	BIO_flush(out);

	message(out,"BN_lshift");
	if (!test_lshift(out,ctx,NULL)) goto err;
	BIO_flush(out);

	message(out,"BN_rshift1");
	if (!test_rshift1(out)) goto err;
	BIO_flush(out);

	message(out,"BN_rshift");
	if (!test_rshift(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_sqr");
	if (!test_sqr(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_mul");
	if (!test_mul(out)) goto err;
	BIO_flush(out);

	message(out,"BN_div");
	if (!test_div(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_div_recp");
	if (!test_div_recp(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_mod");
	if (!test_mod(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_mod_mul");
	if (!test_mod_mul(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_mont");
	if (!test_mont(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_mod_exp");
	if (!test_mod_exp(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_exp");
	if (!test_exp(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_kronecker");
	if (!test_kron(out,ctx)) goto err;
	BIO_flush(out);

	message(out,"BN_mod_sqrt");
	if (!test_sqrt(out,ctx)) goto err;
	BIO_flush(out);

	BN_CTX_free(ctx);
	BIO_free(out);

/**/
	EXIT(0);
err:
	BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
	                      * the failure, see test_bn in test/Makefile.ssl*/
	BIO_flush(out);
	ERR_load_crypto_strings();
	ERR_print_errors_fp(stderr);
	EXIT(1);
	return(1);
	}
示例#6
0
static void
digest(struct executable *x)
{
    EVP_MD_CTX *mdctx;
    const EVP_MD *md;
    size_t sum_of_bytes_hashed;
    int i, ok;

    /*
     * Windows Authenticode Portable Executable Signature Format
     * spec version 1.0 specifies MD5 and SHA1.  However, pesign
     * and sbsign both use SHA256, so do the same.
     */
    md = EVP_get_digestbyname(DIGEST);
    if (md == NULL) {
        ERR_print_errors_fp(stderr);
        errx(1, "EVP_get_digestbyname(\"%s\") failed", DIGEST);
    }

    mdctx = EVP_MD_CTX_create();
    if (mdctx == NULL) {
        ERR_print_errors_fp(stderr);
        errx(1, "EVP_MD_CTX_create(3) failed");
    }

    ok = EVP_DigestInit_ex(mdctx, md, NULL);
    if (ok == 0) {
        ERR_print_errors_fp(stderr);
        errx(1, "EVP_DigestInit_ex(3) failed");
    }

    /*
     * According to the Authenticode spec, we need to compute
     * the digest in a rather... specific manner; see "Calculating
     * the PE Image Hash" part of the spec for details.
     *
     * First, everything from 0 to before the PE checksum.
     */
    digest_range(x, mdctx, 0, x->x_checksum_off);

    /*
     * Second, from after the PE checksum to before the Certificate
     * entry in Data Directory.
     */
    digest_range(x, mdctx, x->x_checksum_off + x->x_checksum_len,
                 x->x_certificate_entry_off -
                 (x->x_checksum_off + x->x_checksum_len));

    /*
     * Then, from after the Certificate entry to the end of headers.
     */
    digest_range(x, mdctx,
                 x->x_certificate_entry_off + x->x_certificate_entry_len,
                 x->x_headers_len -
                 (x->x_certificate_entry_off + x->x_certificate_entry_len));

    /*
     * Then, each section in turn, as specified in the PE Section Table.
     *
     * XXX: Sorting.
     */
    sum_of_bytes_hashed = x->x_headers_len;
    for (i = 0; i < x->x_nsections; i++) {
        digest_range(x, mdctx,
                     x->x_section_off[i], x->x_section_len[i]);
        sum_of_bytes_hashed += x->x_section_len[i];
    }

    /*
     * I believe this can happen with overlapping sections.
     */
    if (sum_of_bytes_hashed > x->x_len)
        errx(1, "number of bytes hashed is larger than file size");

    /*
     * I can't really explain this one; just do what the spec says.
     */
    if (sum_of_bytes_hashed < x->x_len) {
        digest_range(x, mdctx, sum_of_bytes_hashed,
                     x->x_len - (signature_size(x) + sum_of_bytes_hashed));
    }

    ok = EVP_DigestFinal_ex(mdctx, x->x_digest, &x->x_digest_len);
    if (ok == 0) {
        ERR_print_errors_fp(stderr);
        errx(1, "EVP_DigestFinal_ex(3) failed");
    }

    EVP_MD_CTX_destroy(mdctx);
}
示例#7
0
/**
 * \brief Funtion that listens for new connetions
 *
 * Runs in a thread and adds new connections to plugin_conf->master set
 *
 * \param[in, out] config Plugin configuration structure
 * \return NULL always
 */
void *input_listen(void *config)
{
	struct plugin_conf *conf = (struct plugin_conf *) config;
	int new_sock;
	/* use IPv6 sockaddr structure to store address information (IPv4 fits easily) */
	struct sockaddr_in6 *address = NULL;
	socklen_t addr_length;
	char src_addr[INET6_ADDRSTRLEN];
	struct input_info_list *input_info;
#ifdef TLS_SUPPORT
	int ret;
	int i;
	SSL *ssl = NULL;           /* structure for TLS connection */
	X509 *peer_cert = NULL;    /* peer's certificate */
	struct cleanup maid;       /* auxiliary struct for TLS error handling */
#endif

	/* loop ends when thread is cancelled by pthread_cancel() function */
	while (1) {
		/* allocate space for the address */
		addr_length = sizeof(struct sockaddr_in6);
		address = malloc(addr_length);
		if (!address) {
			MSG_ERROR(msg_module, "Memory allocation failed (%s:%d)", __FILE__, __LINE__);
			break;
		}

		/* ensure that address will be freed when thread is canceled */ 
		pthread_cleanup_push(input_listen_cleanup, (void *) address);

		if ((new_sock = accept(conf->socket, (struct sockaddr*) address, &addr_length)) == -1) {
			MSG_ERROR(msg_module, "Cannot accept new socket: %s", strerror(errno));
			/* exit and call cleanup */
			pthread_exit(0);
		}
#ifdef TLS_SUPPORT
		/* preparation for TLS error handling */
		maid.address = address;
		maid.ssl = NULL;
		maid.peer_cert = NULL;

		if (conf->tls) {
			/* create a new SSL structure for the connection */
			ssl = SSL_new(conf->ctx);
			if (!ssl) {
				MSG_ERROR(msg_module, "Unable to create SSL structure");
				ERR_print_errors_fp(stderr);
				/* cleanup */
				input_listen_tls_cleanup(conf, &maid);
				continue;
			}
			maid.ssl = ssl;

			/* connect the SSL object with the socket */
			ret = SSL_set_fd(ssl, new_sock);
			if (ret != 1) {
				MSG_ERROR(msg_module, "Unable to connect the SSL object with the socket");
				ERR_print_errors_fp(stderr);
				/* cleanup */
				input_listen_tls_cleanup(conf, &maid);
				continue;
			}

			/* TLS handshake */
			ret = SSL_accept(ssl);
			if (ret != 1) {
				/* handshake wasn't successful */
				MSG_ERROR(msg_module, "TLS handshake was not successful");
				ERR_print_errors_fp(stderr);
				/* cleanup */
				input_listen_tls_cleanup(conf, &maid);
				continue;
			}

			/* obtain peer's certificate */
			peer_cert = SSL_get_peer_certificate(ssl);
			if (!peer_cert) {
				MSG_ERROR(msg_module, "No certificate was presented by the peer");
				/* cleanup */
				input_listen_tls_cleanup(conf, &maid);
				continue;
			}
			maid.peer_cert = peer_cert;

			/* verify peer's certificate */
			if (SSL_get_verify_result(ssl) != X509_V_OK) {
				MSG_ERROR(msg_module, "Client sent bad certificate; verification failed");
				/* cleanup */
				input_listen_tls_cleanup(conf, &maid);
				continue;
			}

			/* put new SSL structure into the conf->ssl_list */
			for (i = 0; i < conf->ssl_list_size; i++) {
				if (conf->ssl_list[i] == NULL) {
					conf->ssl_list[i] = ssl;
				}
			}

			if (conf->ssl_list[i] != ssl) {
				/* limit reached. no space for new SSL structure */
				MSG_WARNING(msg_module, "Reached limit on the number of TLS connections; tearing down this connection...");
				/* cleanup */
				input_listen_tls_cleanup(conf, &maid);
				continue;
			}
		}
#endif
		pthread_mutex_lock(&mutex);
		FD_SET(new_sock, &conf->master);

		if (conf->fd_max < new_sock) {
			conf->fd_max = new_sock;
		}

		/* copy socket address to config structure */
		if (!add_sock_address(conf, address, new_sock)) {
			MSG_ERROR(msg_module, "Cannot store another socket address");
			break;
		}

		/* print info */
		if (conf->info.l3_proto == 4) {
			inet_ntop(AF_INET, (void *)&((struct sockaddr_in*) address)->sin_addr, src_addr, INET6_ADDRSTRLEN);
		} else {
			inet_ntop(AF_INET6, &address->sin6_addr, src_addr, INET6_ADDRSTRLEN);
		}
		MSG_INFO(msg_module, "Exporter connected from address %s", src_addr);

		pthread_mutex_unlock(&mutex);

		/* create new input_info for this connection */
		input_info = calloc(1, sizeof(struct input_info_list));
		if (input_info == NULL) {
			MSG_ERROR(msg_module, "Memory allocation failed (%s:%d)", __FILE__, __LINE__);
			break;
		}

		memcpy(&input_info->info, &conf->info, sizeof(struct input_info_network));

		/* set status to new connection */
		input_info->info.status = SOURCE_STATUS_NEW;

		/* copy address and port */
		if (address->sin6_family == AF_INET) {
			/* copy src IPv4 address */
			input_info->info.src_addr.ipv4.s_addr =
					((struct sockaddr_in*) address)->sin_addr.s_addr;

			/* copy port */
			input_info->info.src_port = ntohs(((struct sockaddr_in*)  address)->sin_port);
		} else {
			/* copy src IPv6 address */
			int i;
			for (i=0; i<4; i++) {
				input_info->info.src_addr.ipv6.s6_addr32[i] = address->sin6_addr.s6_addr32[i];
			}

			/* copy port */
			input_info->info.src_port = ntohs(address->sin6_port);
		}

#ifdef TLS_SUPPORT
		/* fill in certificates */
		input_info->collector_cert = conf->server_cert_file;
		input_info->exporter_cert = peer_cert;
#endif

		/* add to list */
		input_info->next = conf->info_list;
		conf->info_list = input_info;

		/* unset the address so that we do not free it incidentally */
		address = NULL;

		pthread_cleanup_pop(0);
	}
	return NULL;
}
示例#8
0
int fips_check_rsa(RSA *rsa)
    {
    int n, ret = 0;
    unsigned char tctext[256], *ctext = tctext;
    unsigned char tptext[256], *ptext = tptext;
    /* The longest we can have with PKCS#1 v1.5 padding and a 512 bit key,
     * namely 512/8-11-1 = 52 bytes */
    static const unsigned char original_ptext[] =
	"\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
	"\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
	"\x01\x23\x45\x67\x89\xab\xcd\xef\x01\x23\x45\x67\x89\xab\xcd\xef"
	"\x01\x23\x45\x67";

    if (RSA_size(rsa) > sizeof(tctext))
	{
	ctext = OPENSSL_malloc(RSA_size(rsa));
	ptext = OPENSSL_malloc(RSA_size(rsa));
	if (!ctext || !ptext)
		{
		ERR_print_errors_fp(OPENSSL_stderr());
		exit(1);
		}
	}
	

    /* this will fail for keys shorter than 512 bits */
    n=RSA_private_encrypt(sizeof(original_ptext)-1,original_ptext,ctext,rsa,
			 RSA_PKCS1_PADDING);
    if(n < 0)
	{
	ERR_print_errors_fp(OPENSSL_stderr());
	exit(1);
	}
    if(!memcmp(ctext,original_ptext,n))
  	{
  	FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
 	goto error;
 	}
    n=RSA_public_decrypt(n,ctext,ptext,rsa,RSA_PKCS1_PADDING);
    if(n < 0)
	{
	ERR_print_errors_fp(OPENSSL_stderr());
	exit(1);
	}
    if(n != sizeof(original_ptext)-1 || memcmp(ptext,original_ptext,n))
	{
	FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
	goto error;
	}

    ret = 1;

    error:

    if (RSA_size(rsa) > sizeof(tctext))
	{
	OPENSSL_free(ctext);
	OPENSSL_free(ptext);
	}

    return ret;
    }
示例#9
0
krb5_data *
krb5_cproxy_process(char *servername, char *port, krb5_data *request) {
  /* SSL init */
  SSL_library_init(); /* always returns 1 */
  SSL_load_error_strings();
  OpenSSL_add_all_algorithms();
  const SSL_METHOD *method = SSLv23_client_method(); /* includes TLSv1 */
  if (!method) {
    ERR_print_errors_fp(stderr);
    EVP_cleanup();
    return NULL;
  }
  SSL_CTX *gamma = SSL_CTX_new(method);
  if (!gamma) {
    ERR_print_errors_fp(stderr);
    EVP_cleanup();
    return NULL;
  }
  SSL_CTX_set_verify(gamma, SSL_VERIFY_PEER, NULL);
  if (!SSL_CTX_set_default_verify_paths(gamma)) {
    ERR_print_errors_fp(stderr);
    SSL_CTX_free(gamma);
    EVP_cleanup();
    return NULL;
  }
  SSL *ssl = SSL_new(gamma);
  if (!ssl) {
    ERR_print_errors_fp(stderr);
    SSL_CTX_free(gamma);
    EVP_cleanup();
    return NULL;
  }

  /* Encoding */
  char *req;
  gsize out_len;
  char *fmt = "POST / HTTP/1.0\r\n"
    "Host: %s\r\n" /* MSFT gets upset without this */
    "Content-type: application/kerberos\r\n"
    "Content-length: %d\r\n"
    "\r\n%s";
  char *g_buf = g_base64_encode((guchar *) request->data, request->length);
  size_t reqlen = asprintf(&req, fmt, servername, strlen(g_buf), g_buf);
  g_free(g_buf);

  /* connect to other proxy */
  struct addrinfo khints, *kserverdata;
  memset(&khints, 0, sizeof(khints));
  khints.ai_family = AF_UNSPEC;
  khints.ai_socktype = SOCK_STREAM;   /* TCP for HTTP */
  int gai_ret = getaddrinfo(servername, port, &khints, &kserverdata);
  if (gai_ret) {
    fprintf(stderr, "%s\n", gai_strerror(gai_ret));
    SSL_CTX_free(gamma);
    EVP_cleanup();
    free(req);
    return NULL;
  }

  int fd_prox = -1;
  for (struct addrinfo *cur = kserverdata;
       cur != NULL && fd_prox == -1;
       cur = cur->ai_next) {
    fd_prox = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
    if (fd_prox == -1) {
      fprintf(stderr, "failed to socket\n");
    } else if (connect(fd_prox, cur->ai_addr, cur->ai_addrlen) == -1) {
      close(fd_prox);
      fd_prox = -1;
      fprintf(stderr, "failed to connect\n");
    }
  }
  freeaddrinfo(kserverdata);
  if (fd_prox == -1) {
    fprintf(stderr, "unable to connect to any sockets\n");
    SSL_CTX_free(gamma);
    EVP_cleanup();
    free(req);
    return NULL;
  }

  /* SSL the socket */
  if (!SSL_set_fd(ssl, fd_prox)) {
    ERR_print_errors_fp(stderr);
    close(fd_prox);
    free(req);
    SSL_free(ssl);
    SSL_CTX_free(gamma);
    EVP_cleanup();
    return NULL;
  }
  if (SSL_connect(ssl) != 1) {
    ERR_print_errors_fp(stderr); /* maybe? */
    close(fd_prox);
    free(req);
    SSL_free(ssl);
    SSL_CTX_free(gamma);
    EVP_cleanup();
    return NULL;
  }

  /* send, get the KDCPROXY's reply */
  if (!SSL_write(ssl, req, reqlen)) {
    ERR_print_errors_fp(stderr); /* maybe */
    close(fd_prox);
    SSL_free(ssl);
    SSL_CTX_free(gamma);
    EVP_cleanup();
    return NULL;
  }
  free(req);

  char buf[BUF_SIZE];
  char *bufptr = buf;
  int length;
  do {
    length = SSL_read(ssl, bufptr, BUF_SIZE - 1 + bufptr - buf);
    printf("length: %d\n", length);
    if (length < 0) {
      ERR_print_errors_fp(stderr); /* maybe? */
      close(fd_prox);
      SSL_free(ssl);
      SSL_CTX_free(gamma);
      EVP_cleanup();
      return NULL;
    }
    bufptr += length;
  } while (length > 0);
  *bufptr = '\0';

  close(fd_prox);
  SSL_free(ssl);
  SSL_CTX_free(gamma);
  EVP_cleanup();

  /* forward the reply to the requester */
  char *rep = strstr(buf, "\r\n\r\n");
  if (rep == NULL) {
    fprintf(stderr, "didn't get back krb response from proxy\n");
    return NULL;
  }
  rep += 4;

  guchar *res = g_base64_decode(rep, &out_len);

  krb5_data *response = malloc(sizeof(krb5_data));
  response->length = out_len;
  response->data = malloc(sizeof(char)*(out_len + 1));
  memcpy(response->data, res, out_len);
  (response->data)[out_len] = '\0';

  g_free(res);
  return response;
}
示例#10
0
文件: sscep.c 项目: flomar/sscep
int
main(int argc, char **argv) {
	//ENGINE *e = NULL;
	int			c, host_port = 80, count = 1;
	char			*host_name, *p, *dir_name = NULL;
	char			http_string[16384];
	struct http_reply	reply;
	unsigned int		n;
	unsigned char		md[EVP_MAX_MD_SIZE];
	struct scep		scep_t;
	FILE			*fp = NULL;
	BIO			*bp;
	STACK_OF(X509)		*nextcara = NULL;
	X509 				*cert=NULL;
	PKCS7 p7;
	int i;
	int required_option_space;
	


#ifdef WIN32
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	//printf("Starting sscep\n");
	//fprintf(stdout, "%s: starting sscep on WIN32, sscep version %s\n",	pname, VERSION);
       
	wVersionRequested = MAKEWORD( 2, 2 );
 
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 )
	{
	  /* Tell the user that we could not find a usable */
	  /* WinSock DLL.                                  */
	  return;
	}
 
	/* Confirm that the WinSock DLL supports 2.2.*/
	/* Note that if the DLL supports versions greater    */
	/* than 2.2 in addition to 2.2, it will still return */
	/* 2.2 in wVersion since that is the version we      */
	/* requested.                                        */
 
	if ( LOBYTE( wsaData.wVersion ) != 2 ||
	        HIBYTE( wsaData.wVersion ) != 2 )
	{
	    /* Tell the user that we could not find a usable */
	    /* WinSock DLL.                                  */
	    WSACleanup( );
	    return; 
	}

#endif
	/* Initialize scep layer */
	init_scep();

	/* Set program name */
	pname = argv[0];

	/* Set timeout */
	timeout = TIMEOUT;


	/* Check operation parameter */
	if (!argv[1]) {
		usage();
	} else if (!strncmp(argv[1], "getca", 5)) {
		operation_flag = SCEP_OPERATION_GETCA;
	} else if (!strncmp(argv[1], "enroll", 6)) {
		operation_flag = SCEP_OPERATION_ENROLL;
	} else if (!strncmp(argv[1], "getcert", 7)) {
		operation_flag = SCEP_OPERATION_GETCERT;
	} else if (!strncmp(argv[1], "getcrl", 6)) {
		operation_flag = SCEP_OPERATION_GETCRL;
	} else if (!strncmp(argv[1], "getnextca", 9)) {
		operation_flag = SCEP_OPERATION_GETNEXTCA;
	} else {
		fprintf(stderr, "%s: missing or illegal operation parameter\n",
				argv[0]);
		usage();
	}
	/* Skip first parameter and parse the rest of the command */
	optind++;
	while ((c = getopt(argc, argv, "c:C:de:E:f:g:hF:i:k:K:l:L:n:O:p:r:Rs:S:t:T:u:vw:m:HM:")) != -1)
                switch(c) {
			case 'c':
				c_flag = 1;
				c_char = optarg;
				break;
			case 'C':
				C_flag = 1;
				C_char = optarg;
				break;
			case 'd':
				d_flag = 1;
				break;
			case 'e':
				e_flag = 1;
				e_char = optarg;
				break;
			case 'E':
				E_flag = 1;
				E_char = optarg;
				break;
			case 'F':
				F_flag = 1;
				F_char = optarg;
				break;
			case 'f':
				f_flag = 1;
				f_char = optarg;
				break;
			case 'g':
				g_flag = 1;
				g_char = optarg;
				break;
			case 'h'://TODO change to eg. ID --inform=ID
				h_flag = 1;
				break;
			case 'H':
				H_flag = 1;
				break;
			case 'i':
				i_flag = 1;
				i_char = optarg;
				break;
			case 'k':
				k_flag = 1;
				k_char = optarg;
				break;
			case 'K':
				K_flag = 1;
				K_char = optarg;
				break;
			case 'l':
				l_flag = 1;
				l_char = optarg;
				break;
			case 'L':
				L_flag = 1;
				L_char = optarg;
				break;
			case 'm':
				m_flag = 1;
				m_char = optarg;
				break;
			case 'M':
				if(!M_flag) {
					/* if this is the first time the option appears, create a
					 * new string.
					 */
					required_option_space = strlen(optarg) + 1;
					M_char = malloc(required_option_space);
					if(!M_char)
						error_memory();
					strncpy(M_char, optarg, required_option_space);
					// set the flag, so we already have a string
					M_flag = 1;
				} else {
					/* we already have a string, just extend it. */
					// old part + new part + &-sign + null byte
					required_option_space = strlen(M_char) + strlen(optarg) + 2;
					M_char = realloc(M_char, required_option_space);
					if(!M_char)
						error_memory();
					strncat(M_char, "&", 1);
					strncat(M_char, optarg, strlen(optarg));
				}
				break;
			case 'n':
				n_flag = 1;
				n_num = atoi(optarg);
				break;
			case 'O':
				O_flag = 1;
				O_char = optarg;
				break;
			case 'p':
				p_flag = 1;
				p_char = optarg;
				break;
			case 'r':
				r_flag = 1;
				r_char = optarg;
				break;
			case 'R':
				R_flag = 1;
				break;
			case 's':
				s_flag = 1;
				/*s_char = optarg;*/
				s_char = handle_serial(optarg);
				break;
			case 'S':
				S_flag = 1;
				S_char = optarg;
				break;
			case 't':
				t_flag = 1;
				t_num = atoi(optarg);
				break;
			case 'T':
				T_flag = 1;
				T_num = atoi(optarg);
				break;
			case 'u':
				u_flag = 1;
				url_char = optarg;
				break;
			case 'v':
				v_flag = 1;
				break;
			case 'w':
				w_flag = 1;
				w_char = optarg;
				break;
			default:
			  printf("argv: %s\n", argv[optind]);
				usage();
                }
	argc -= optind;
	argv += optind;

	/* If we debug, include verbose messages also */
	if (d_flag)
		v_flag = 1;
	
	if(f_char){
		scep_conf_init(f_char);
	}else{
		scep_conf = NULL;    //moved init to here otherwise compile error on windows
	}
	/* Read in the configuration file: */
	/*if (f_char) {
	#ifdef WIN32
		if ((fopen_s(&fp, f_char, "r")))
	#else
		if (!(fp = fopen(f_char, "r")))
	#endif
			fprintf(stderr, "%s: cannot open %s\n", pname, f_char);
		else {
			init_config(fp);
			(void)fclose(fp);
		}
	}*/
	if (v_flag)
		fprintf(stdout, "%s: starting sscep, version %s\n",
			pname, VERSION);

	/*
	* Create a new SCEP transaction and self-signed
	* certificate based on cert request
	*/
	if (v_flag)
		fprintf(stdout, "%s: new transaction\n", pname);
	new_transaction(&scep_t);

	/*enable Engine Support */
	if (g_flag) {
		scep_t.e = scep_engine_init(scep_t.e);
	}
	
	/*
	 * Check argument logic.
	 */
	if (!c_flag) {
		if (operation_flag == SCEP_OPERATION_GETCA) {
			fprintf(stderr,
			  "%s: missing CA certificate filename (-c)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		} else {
			fprintf(stderr,
				"%s: missing CA certificate (-c)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (operation_flag == SCEP_OPERATION_GETNEXTCA) {
			fprintf(stderr,
			  "%s: missing nextCA certificate target filename (-c)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		} else {
			fprintf(stderr,
				"%s: missing nextCA certificate target filename(-c)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
	}
	if (!C_flag) {
		if (operation_flag == SCEP_OPERATION_GETNEXTCA) {
			fprintf(stderr,
			  "%s: missing nextCA certificate chain filename (-C)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
	}
	if (operation_flag == SCEP_OPERATION_ENROLL) {
		if (!k_flag) {
			fprintf(stderr, "%s: missing private key (-k)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!r_flag) {
			fprintf(stderr, "%s: missing request (-r)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);

		}
		if (!l_flag) {
			fprintf(stderr, "%s: missing local cert (-l)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		/* Set polling limits */
		if (!n_flag)
			n_num = MAX_POLL_COUNT;
		if (!t_flag)
			t_num = POLL_TIME;
		if (!T_flag)
			T_num = MAX_POLL_TIME;
	}
	if (operation_flag == SCEP_OPERATION_GETCERT) {
		if (!l_flag) {
			fprintf(stderr, "%s: missing local cert (-l)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!s_flag) {
			fprintf(stderr, "%s: missing serial no (-s)\n", pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!w_flag) {
			fprintf(stderr, "%s: missing cert file (-w)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!k_flag) {
			fprintf(stderr, "%s: missing private key (-k)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
	}
	if (operation_flag == SCEP_OPERATION_GETCRL) {
		if (!l_flag) {
			fprintf(stderr, "%s: missing local cert (-l)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!w_flag) {
			fprintf(stderr, "%s: missing crl file (-w)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
		if (!k_flag) {
			fprintf(stderr, "%s: missing private key (-k)\n",pname);
			exit (SCEP_PKISTATUS_ERROR);
		}
	}

	/* Break down the URL */
	if (!u_flag) {
		fprintf(stderr, "%s: missing URL (-u)\n", pname);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (strncmp(url_char, "http://", 7) && !p_flag) {
		fprintf(stderr, "%s: illegal URL %s\n", pname, url_char);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (p_flag) {
		#ifdef WIN32
		host_name = _strdup(p_char);
		#else
		host_name = strdup(p_char);
		#endif
		dir_name = url_char;
	}

	/* Break down the URL */
	if (!u_flag) {
		fprintf(stderr, "%s: missing URL (-u)\n", pname);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (strncmp(url_char, "http://", 7) && !p_flag) {
		fprintf(stderr, "%s: illegal URL %s\n", pname, url_char);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (p_flag) {
		#ifdef WIN32
		host_name = _strdup(p_char);
		#else
		host_name = strdup(p_char);
		#endif
		dir_name = url_char;
	}
	#ifdef WIN32
	else if (!(host_name = _strdup(url_char + 7)))
	#else
	else if (!(host_name = strdup(url_char + 7)))
	#endif
		error_memory();
	p = host_name;
	c = 0;
	while (*p != '\0') {
		if (*p == '/' && !p_flag && !c) {
			*p = '\0';
			if (*(p+1)) dir_name = p + 1;
			c = 1;
		}
		if (*p == ':') {
			*p = '\0';
			if (*(p+1)) host_port = atoi(p+1);
		}
		p++;
	}
	if (!dir_name) {
		fprintf(stderr, "%s: illegal URL %s\n", pname, url_char);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (host_port < 1 || host_port > 65550) {
		fprintf(stderr, "%s: illegal port number %d\n", pname,
				host_port);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (v_flag) {
		fprintf(stdout, "%s: hostname: %s\n", pname, host_name);
		fprintf(stdout, "%s: directory: %s\n", pname, dir_name);
		fprintf(stdout, "%s: port: %d\n", pname, host_port);
	}

	/* Check algorithms */
	if (!E_flag) {
		enc_alg = (EVP_CIPHER *)EVP_des_cbc();
	} else if (!strncmp(E_char, "blowfish", 8)) {
		enc_alg = (EVP_CIPHER *)EVP_bf_cbc();
	} else if (!strncmp(E_char, "des", 3)) {
		enc_alg = (EVP_CIPHER *)EVP_des_cbc();
	} else if (!strncmp(E_char, "3des", 4)) {
		enc_alg = (EVP_CIPHER *)EVP_des_ede3_cbc();
	} else if (!strncmp(E_char, "aes", 3)) {
		enc_alg = (EVP_CIPHER *)EVP_aes_256_cbc();
	} else {
		fprintf(stderr, "%s: unsupported algorithm: %s\n",
			pname, E_char);
		exit (SCEP_PKISTATUS_ERROR);
	}
	if (!S_flag) {
		sig_alg = (EVP_MD *)EVP_md5();
	} else if (!strncmp(S_char, "md5", 3)) {
		sig_alg = (EVP_MD *)EVP_md5();
	} else if (!strncmp(S_char, "sha1", 4)) {
		sig_alg = (EVP_MD *)EVP_sha1();
	} else {
		fprintf(stderr, "%s: unsupported algorithm: %s\n",
			pname, S_char);
		exit (SCEP_PKISTATUS_ERROR);
	}
	/* Fingerprint algorithm */
	if (!F_flag) {
		fp_alg = (EVP_MD *)EVP_md5();
	} else if (!strncmp(F_char, "md5", 3)) {
		fp_alg = (EVP_MD *)EVP_md5();
	} else if (!strncmp(F_char, "sha1", 4)) {
		fp_alg = (EVP_MD *)EVP_sha1();
	} else {
		fprintf(stderr, "%s: unsupported algorithm: %s\n",
			pname, F_char);
		exit (SCEP_PKISTATUS_ERROR);
	}

	/*
	 * Switch to operation specific code
	 */
	switch(operation_flag) {
		case SCEP_OPERATION_GETCA:
			if (v_flag)
				fprintf(stdout, "%s: SCEP_OPERATION_GETCA\n",
					pname);

			/* Set CA identifier */
			if (!i_flag)
				i_char = CA_IDENTIFIER;

			/* Forge the HTTP message */

			if(!M_flag){
				snprintf(http_string, sizeof(http_string),
				 "GET %s%s?operation=GetCACert&message=%s "
				 "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,
						i_char);

			}else{
				snprintf(http_string, sizeof(http_string),
					"GET %s%s?operation=GetCACert&message=%s&%s "
					"HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,
						i_char, M_char);

			}



			if (d_flag){
				printf("%s: requesting CA certificate\n", pname);
				fprintf(stdout, "%s: scep msg: %s", pname,
									http_string);
			}

			/*
			 * Send http message.
			 * Response is written to http_response struct "reply".
			 */
			reply.payload = NULL;
			if ((c = send_msg (&reply, http_string, host_name,
					host_port, operation_flag)) == 1) {
				fprintf(stderr, "%s: error while sending "
					"message\n", pname);
				exit (SCEP_PKISTATUS_NET);
			}
			if (reply.payload == NULL) {
				fprintf(stderr, "%s: no data, perhaps you "
				   "should define CA identifier (-i)\n", pname);
				exit (SCEP_PKISTATUS_SUCCESS);
			}
			if (v_flag){
				printf("%s: valid response from server\n", pname);
			}
			if (reply.type == SCEP_MIME_GETCA_RA) {
				/* XXXXXXXXXXXXXXXXXXXXX chain not verified */
				write_ca_ra(&reply);
			}
			/* Read payload as DER X.509 object: */
			bp = BIO_new_mem_buf(reply.payload, reply.bytes);
			cacert = d2i_X509_bio(bp, NULL);

			/* Read and print certificate information */
			if (!X509_digest(cacert, fp_alg, md, &n)) {
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_ERROR);
			}
			if (v_flag){
				printf("%s: %s fingerprint: ", pname,
					OBJ_nid2sn(EVP_MD_type(fp_alg)));
				for (c = 0; c < (int)n; c++) {
					printf("%02X%c",md[c],
						(c + 1 == (int)n) ?'\n':':');
				}

			}

			/* Write PEM-formatted file: */
			#ifdef WIN32
			if ((fopen_s(&fp,c_char , "w")))
			#else
			if (!(fp = fopen(c_char, "w")))
			#endif
			{
				fprintf(stderr, "%s: cannot open CA file for "
					"writing\n", pname);
				exit (SCEP_PKISTATUS_ERROR);
			}
			if (PEM_write_X509(fp, c_char) != 1) {
				fprintf(stderr, "%s: error while writing CA "
					"file\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_ERROR);
			}
			if (v_flag)
			printf("%s: CA certificate written as %s\n",
				pname, c_char);
			(void)fclose(fp);
			pkistatus = SCEP_PKISTATUS_SUCCESS;
			break;

		case SCEP_OPERATION_GETNEXTCA:
				if (v_flag)
					fprintf(stdout, "%s: SCEP_OPERATION_GETNEXTCA\n",
						pname);

				/* Set CA identifier */
				if (!i_flag)
					i_char = CA_IDENTIFIER;

				/* Forge the HTTP message */
				if(!M_flag){
					snprintf(http_string, sizeof(http_string),
					 "GET %s%s?operation=GetNextCACert&message=%s "
					 "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,
							i_char);

				}else{
					snprintf(http_string, sizeof(http_string),
						"GET %s%s?operation=GetNextCACert&message=%s&%s "
						"HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,
							i_char, M_char);

				}


				if (d_flag){
					printf("%s: requesting nextCA certificate\n", pname);
					fprintf(stdout, "%s: scep msg: %s", pname,
						http_string);
				}

				/*
				 * Send http message.
				 * Response is written to http_response struct "reply".
				 */
				reply.payload = NULL;
				if ((c = send_msg (&reply, http_string, host_name,
						host_port, operation_flag)) == 1) {
					if(v_flag){
					fprintf(stderr, "%s: error while sending "
						"message\n", pname);
					fprintf(stderr, "%s: getnextCA might be not available"
											"\n", pname);
					}
					exit (SCEP_PKISTATUS_NET);
				}
				if (reply.payload == NULL) {
					fprintf(stderr, "%s: no data, perhaps you "
					   "there is no nextCA available\n", pname);
					exit (SCEP_PKISTATUS_SUCCESS);
				}

				if(d_flag)
				printf("%s: valid response from server\n", pname);

				if (reply.type == SCEP_MIME_GETNEXTCA) {
					/* XXXXXXXXXXXXXXXXXXXXX chain not verified */

					//write_ca_ra(&reply);

					/* Set the whole struct as 0 */
					memset(&scep_t, 0, sizeof(scep_t));

					scep_t.reply_payload = reply.payload;
					scep_t.reply_len = reply.bytes;
					scep_t.request_type = SCEP_MIME_GETNEXTCA;

					pkcs7_verify_unwrap(&scep_t , C_char);

					//pkcs7_unwrap(&scep_t);
				}


				/* Get certs */
				p7 = *(scep_t.reply_p7);
				nextcara = scep_t.reply_p7->d.sign->cert;

			    if (v_flag) {
					printf ("verify and unwrap: found %d cert(s)\n", sk_X509_num(nextcara));
			        }

			    for (i = 0; i < sk_X509_num(nextcara); i++) {
			    		char buffer[1024];
			    		char name[1024];
			    		memset(buffer, 0, 1024);
			    		memset(name, 0, 1024);

			    		cert = sk_X509_value(nextcara, i);
			    		if (v_flag) {
			    			printf("%s: found certificate with\n"
			    				"  subject: '%s'\n", pname,
			    				X509_NAME_oneline(X509_get_subject_name(cert),
			    					buffer, sizeof(buffer)));
			    			printf("  issuer: %s\n",
			    				X509_NAME_oneline(X509_get_issuer_name(cert),
			    					buffer, sizeof(buffer)));
			    		}

			    		/* Create name */
			    		snprintf(name, 1024, "%s-%d", c_char, i);


			    		/* Write PEM-formatted file: */
			    		if (!(fp = fopen(name, "w"))) {
			    			fprintf(stderr, "%s: cannot open cert file for writing\n",
			    					pname);
			    			exit (SCEP_PKISTATUS_FILE);
			    		}
			    		if (v_flag)
			    			printf("%s: writing cert\n", pname);
			    		if (d_flag)
			    			PEM_write_X509(stdout, cert);
			    		if (PEM_write_X509(fp, cert) != 1) {
			    			fprintf(stderr, "%s: error while writing certificate "
			    				"file\n", pname);
			    			ERR_print_errors_fp(stderr);
			    			exit (SCEP_PKISTATUS_FILE);
			    		}
			    		if(v_flag)
			    		printf("%s: certificate written as %s\n", pname, name);
			    		(void)fclose(fp);
			    }



				pkistatus = SCEP_PKISTATUS_SUCCESS;
				break;

		case SCEP_OPERATION_GETCERT:
		case SCEP_OPERATION_GETCRL:
			/* Read local certificate */
			if (!l_flag) {
			  fprintf(stderr, "%s: missing local cert (-l)\n", pname);
			  exit (SCEP_PKISTATUS_FILE);
			}
			read_cert(&localcert, l_char);

		case SCEP_OPERATION_ENROLL:
			/*
			 * Read in CA cert, private key and certificate
			 * request in global variables.
			 */

		        read_ca_cert();

			if (!k_flag) {
			  fprintf(stderr, "%s: missing private key (-k)\n", pname);
			  exit (SCEP_PKISTATUS_FILE);
			}
			
			if(scep_conf != NULL) {
				sscep_engine_read_key_new(&rsa, k_char, scep_t.e);
			} else {
				read_key(&rsa, k_char);
			}


			if ((K_flag && !O_flag) || (!K_flag && O_flag)) {
			  fprintf(stderr, "%s: -O also requires -K (and vice-versa)\n", pname);
			  exit (SCEP_PKISTATUS_FILE);
			}

			if (K_flag) {
				//TODO auf hwcrhk prfen?
				if(scep_conf != NULL) {
					sscep_engine_read_key_old(&renewal_key, K_char, scep_t.e);
				} else {
					read_key(&renewal_key, K_char);
				}
			}

			if (O_flag) {
				read_cert(&renewal_cert, O_char);
			}

			if (operation_flag == SCEP_OPERATION_ENROLL) {
				read_request();
				scep_t.transaction_id = key_fingerprint(request);			
				if (v_flag) {
					printf("%s:  Read request with transaction id: %s\n", pname, scep_t.transaction_id);
				}
			}

			
			if (operation_flag != SCEP_OPERATION_ENROLL)
				goto not_enroll;
			
			if (! O_flag) {
				if (v_flag)
					fprintf(stdout, "%s: generating selfsigned "
					"certificate\n", pname);
			  new_selfsigned(&scep_t);
			}
			else {
			  /* Use existing certificate */
			  scep_t.signercert = renewal_cert;
			  scep_t.signerkey = renewal_key;
			}

			/* Write the selfsigned certificate if requested */
			if (L_flag) {
				/* Write PEM-formatted file: */
				#ifdef WIN32
				if ((fopen_s(&fp, L_char, "w"))) {
				#else
				if (!(fp = fopen(L_char, "w"))) {
				#endif
					fprintf(stderr, "%s: cannot open "
					  "file for writing\n", pname);
					exit (SCEP_PKISTATUS_ERROR);
				}
				if (PEM_write_X509(fp,scep_t.signercert) != 1) {
					fprintf(stderr, "%s: error while "
					  "writing certificate file\n", pname);
					ERR_print_errors_fp(stderr);
					exit (SCEP_PKISTATUS_ERROR);
				}
				printf("%s: selfsigned certificate written "
					"as %s\n", pname, L_char);
				(void)fclose(fp);
			}
			/* Write issuer name and subject (GetCertInitial): */
			if (!(scep_t.ias_getcertinit->subject =
					X509_REQ_get_subject_name(request))) {
				fprintf(stderr, "%s: error getting subject "
					"for GetCertInitial\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_ERROR);
			}
not_enroll:
			if (!(scep_t.ias_getcertinit->issuer =
					 X509_get_issuer_name(cacert))) {
				fprintf(stderr, "%s: error getting issuer "
					"for GetCertInitial\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_ERROR);
			}
			/* Write issuer name and serial (GETC{ert,rl}): */
			scep_t.ias_getcert->issuer =
				 scep_t.ias_getcertinit->issuer;
			scep_t.ias_getcrl->issuer =
				 scep_t.ias_getcertinit->issuer;
			if (!(scep_t.ias_getcrl->serial =
					X509_get_serialNumber(cacert))) {
				fprintf(stderr, "%s: error getting serial "
					"for GetCertInitial\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_ERROR);
			}
			/* User supplied serial number */
			if (s_flag) {
				BIGNUM *bn;
				ASN1_INTEGER *ai;
				int len = BN_dec2bn(&bn , s_char);
				if (!len || !(ai = BN_to_ASN1_INTEGER(bn, NULL))) {
					fprintf(stderr, "%s: error converting serial\n", pname);
					ERR_print_errors_fp(stderr);
					exit (SCEP_PKISTATUS_SS);
				 }
				 scep_t.ias_getcert->serial = ai;
			}
		break;
	}

	switch(operation_flag) {
		case SCEP_OPERATION_ENROLL:
			if (v_flag)
				fprintf(stdout,
					"%s: SCEP_OPERATION_ENROLL\n", pname);
			/* Resum mode: set GetCertInitial */
			if (R_flag) {
				if (n_num == 0)
					exit (SCEP_PKISTATUS_SUCCESS);
				printf("%s: requesting certificate (#1)\n",
					pname);
				scep_t.request_type = SCEP_REQUEST_GETCERTINIT;
				count++;
			} else {
				printf("%s: sending certificate request\n",
					pname);
				scep_t.request_type = SCEP_REQUEST_PKCSREQ;
			}
			break;

		case SCEP_OPERATION_GETCERT:
			if (v_flag)
				fprintf(stdout,
					"%s: SCEP_OPERATION_GETCERT\n", pname);

			scep_t.request_type = SCEP_REQUEST_GETCERT;
			printf("%s: requesting certificate\n",pname);
			break;

		case SCEP_OPERATION_GETCRL:
			if (v_flag)
				fprintf(stdout,
					"%s: SCEP_OPERATION_GETCRL\n", pname);

			scep_t.request_type = SCEP_REQUEST_GETCRL;
			printf("%s: requesting crl\n",pname);
			break;
		}

		/* Enter polling loop */
		while (scep_t.pki_status != SCEP_PKISTATUS_SUCCESS) {
			/* create payload */
			pkcs7_wrap(&scep_t);

			/* URL-encode */
			p = url_encode((char *)scep_t.request_payload,
				scep_t.request_len);

			/*Test mode print SCEP request and don't send it*/
			if(m_flag){

				/* Write output file : */
#ifdef WIN32
				if ((fopen_s(&fp, m_char, "w")))
#else
				if (!(fp = fopen(m_char, "w")))
#endif
				{
					fprintf(stderr, "%s: cannot open output file for "
						"writing\n", m_char);
				}else
				{
					printf("%s: writing PEM fomatted PKCS#7\n", pname);
							PEM_write_PKCS7(fp, scep_t.request_p7);
				}

				//printf("Print SCEP Request:\n %s\n",scep_t.request_payload);
				return 0;
			}

			/* Forge the HTTP message */
		/*	snprintf(http_string, sizeof(http_string),
				"GET %s%s?operation="
				"PKIOperation&message="
				"%s HTTP/1.0\r\n\r\n",
				p_flag ? "" : "/", dir_name, p);*/

			if(!M_flag){
				snprintf(http_string, sizeof(http_string),
				 "GET %s%s?operation=PKIOperation&message=%s "
				 "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, p);

			}else{
				snprintf(http_string, sizeof(http_string),
					"GET %s%s?operation=PKIOperation&message=%s&%s "
					"HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,p, M_char);

			}

			if (d_flag)
				fprintf(stdout, "%s: scep msg: %s",
					pname, http_string);

			/* send http */
			reply.payload = NULL;
			if ((c = send_msg (&reply, http_string, host_name,
					host_port, operation_flag)) == 1) {
				fprintf(stderr, "%s: error while sending "
					"message\n", pname);
				exit (SCEP_PKISTATUS_NET);
			}
			/* Verisign Onsite returns strange reply...
			 * XXXXXXXXXXXXXXXXXXX */
			if ((reply.status == 200) && (reply.payload == NULL)) {
				/*
				scep_t.pki_status = SCEP_PKISTATUS_PENDING;
				break;
				*/
				exit (SCEP_PKISTATUS_ERROR);
			}
			printf("%s: valid response from server\n", pname);

			/* Check payload */
			scep_t.reply_len = reply.bytes;
			scep_t.reply_payload = (unsigned char *)reply.payload;
			pkcs7_unwrap(&scep_t);
			pkistatus = scep_t.pki_status;

			switch(scep_t.pki_status) {
				case SCEP_PKISTATUS_SUCCESS:
					break;
				case SCEP_PKISTATUS_PENDING:
					/* Check time limits */
					if (((t_num * count) >= T_num) ||
					    (count > n_num)) {
						exit (pkistatus);
					}
					scep_t.request_type =
						SCEP_REQUEST_GETCERTINIT;

					/* Wait for poll interval */
					if (v_flag)
					  printf("%s: waiting for %d secs\n",
						pname, t_num);
					sleep(t_num);
					printf("%s: requesting certificate "
						"(#%d)\n", pname, count);

					/* Add counter */
					count++;
					break;

				case SCEP_PKISTATUS_FAILURE:

					/* Handle failure */
					switch (scep_t.fail_info) {
						case SCEP_FAILINFO_BADALG:
						  exit (SCEP_PKISTATUS_BADALG);
						case SCEP_FAILINFO_BADMSGCHK:
						  exit (SCEP_PKISTATUS_BADMSGCHK);
						case SCEP_FAILINFO_BADREQ:
						  exit (SCEP_PKISTATUS_BADREQ);
						case SCEP_FAILINFO_BADTIME:
						  exit (SCEP_PKISTATUS_BADTIME);
						case SCEP_FAILINFO_BADCERTID:
						  exit (SCEP_PKISTATUS_BADCERTID);
						/* Shouldn't be there... */
						default:
						  exit (SCEP_PKISTATUS_ERROR);
					}
				default:
					fprintf(stderr, "%s: unknown "
						"pkiStatus\n", pname);
					exit (SCEP_PKISTATUS_ERROR);
			}
	}
	/* We got SUCCESS, analyze the reply */
	switch (scep_t.request_type) {

		/* Local certificate */
		case SCEP_REQUEST_PKCSREQ:
		case SCEP_REQUEST_GETCERTINIT:
			write_local_cert(&scep_t);
			break;

		/* Other end entity certificate */
		case SCEP_REQUEST_GETCERT:
			write_other_cert(&scep_t);
			break;

			break;
		/* CRL */
		case SCEP_REQUEST_GETCRL:
			write_crl(&scep_t);
			break;
	}
	//TODO
	//richtiger ort für disable??
//	if(e){
//		ENGINE_finish(*e);
//		ENGINE_free(*e);
//	    hwEngine = NULL;
//	    ENGINE_cleanup();
//	}
//




	return (pkistatus);
}

void
usage() {
	fprintf(stdout, "\nsscep version %s\n\n" , VERSION);
	fprintf(stdout, "Usage: %s OPERATION [OPTIONS]\n"
	"\nAvailable OPERATIONs are\n"
	"  getca             Get CA/RA certificate(s)\n"
	"  getnextca         Get next CA/RA certificate(s)\n"
	"  enroll            Enroll certificate\n"
	"  getcert           Query certificate\n"
	"  getcrl            Query CRL\n"
	"\nGeneral OPTIONS\n"
	"  -u <url>          SCEP server URL\n"
	"  -p <host:port>    Use proxy server at host:port\n"
	"  -M <string>		 Monitor Information String name=value&name=value ...\n"
	"  -g                Enable Engine support\n"
	"  -h				 Keyforme=ID. \n"//TODO
	"  -f <file>         Use configuration file\n"
	"  -c <file>         CA certificate file (write if OPERATION is getca or getnextca)\n"
	"  -E <name>         PKCS#7 encryption algorithm (des|3des|blowfish|aes)\n"
	"  -S <name>         PKCS#7 signature algorithm (md5|sha1)\n"
	"  -v                Verbose operation\n"
	"  -d                Debug (even more verbose operation)\n"
	"\nOPTIONS for OPERATION getca are\n"
	"  -i <string>       CA identifier string\n"
	"  -F <name>         Fingerprint algorithm\n"
	"\nOPTIONS for OPERATION getnextca are\n"
	"  -C <file>         Local certificate chain file for signature verification in PEM format \n"
	"  -F <name>         Fingerprint algorithm\n"
	"  -c <file>         CA certificate file (write if OPERATION is getca or getnextca)\n"
	"  -w <file>         Write signer certificate in file (optional) \n"
	"\nOPTIONS for OPERATION enroll are\n"
 	"  -k <file>         Private key file\n"
	"  -r <file>         Certificate request file\n"
 	"  -K <file>         Signature private key file, use with -O\n"
 	"  -O <file>         Signature certificate (used instead of self-signed)\n"
	"  -l <file>         Write enrolled certificate in file\n"
	"  -e <file>         Use different CA cert for encryption\n"
	"  -L <file>         Write selfsigned certificate in file\n"
	"  -t <secs>         Polling interval in seconds\n"
	"  -T <secs>         Max polling time in seconds\n"
	"  -n <count>        Max number of GetCertInitial requests\n"
 	"  -R                Resume interrupted enrollment\n"
	"\nOPTIONS for OPERATION getcert are\n"
 	"  -k <file>         Private key file\n"
	"  -l <file>         Local certificate file\n"
	"  -s <number>       Certificate serial number\n"
	"  -w <file>         Write certificate in file\n"
	"\nOPTIONS for OPERATION getcrl are\n"
 	"  -k <file>         Private key file\n"
	"  -l <file>         Local certificate file\n"
	"  -w <file>         Write CRL in file\n\n", pname);
	exit(0);
}
示例#11
0
/* Init necessary structures for SSL in WebIf*/
SSL_CTX *SSL_Webif_Init(void)
{
	SSL_library_init();
	SSL_load_error_strings();
	ERR_load_BIO_strings();
	ERR_load_SSL_strings();

	SSL_CTX *ctx;

	static const char *cs_cert = "oscam.pem";

	if(pthread_key_create(&getssl, NULL))
	{
		cs_log("Could not create getssl");
	}

	// set locking callbacks for SSL
	int32_t i, num = CRYPTO_num_locks();
	lock_cs = (CS_MUTEX_LOCK *) OPENSSL_malloc(num * sizeof(CS_MUTEX_LOCK));

	for(i = 0; i < num; ++i)
	{
		cs_lock_create(&lock_cs[i], "ssl_lock_cs", 10000);
	}
	/* static lock callbacks */
	CRYPTO_set_id_callback(SSL_id_function);
	CRYPTO_set_locking_callback(SSL_locking_function);
	/* dynamic lock callbacks */
	CRYPTO_set_dynlock_create_callback(SSL_dyn_create_function);
	CRYPTO_set_dynlock_lock_callback(SSL_dyn_lock_function);
	CRYPTO_set_dynlock_destroy_callback(SSL_dyn_destroy_function);

	if(cfg.http_force_sslv3)
	{
		ctx = SSL_CTX_new(SSLv3_server_method());
#ifdef SSL_CTX_clear_options
		SSL_CTX_clear_options(ctx, SSL_OP_ALL); //we CLEAR all bug workarounds! This is for security reason
#else
		cs_log("WARNING: You enabled to force sslv3 but your system does not support to clear the ssl workarounds! SSL security will be reduced!");
#endif
		SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); // we force SSL v3 !
		SSL_CTX_set_cipher_list(ctx, SSL_TXT_RC4);
	}
	else
		{ ctx = SSL_CTX_new(SSLv23_server_method()); }

	char path[128];

	if(!cfg.http_cert)
		{ get_config_filename(path, sizeof(path), cs_cert); }
	else
		{ cs_strncpy(path, cfg.http_cert, sizeof(path)); }

	if(!ctx)
	{
		ERR_print_errors_fp(stderr);
		return NULL;
	}

	if(SSL_CTX_use_certificate_file(ctx, path, SSL_FILETYPE_PEM) <= 0)
	{
		ERR_print_errors_fp(stderr);
		return NULL;
	}

	if(SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0)
	{
		ERR_print_errors_fp(stderr);
		return NULL;
	}

	if(!SSL_CTX_check_private_key(ctx))
	{
		cs_log("SSL: Private key does not match the certificate public key");
		return NULL;
	}
	cs_log("load ssl certificate file %s", path);
	return ctx;
}
示例#12
0
文件: text_ssl2.c 项目: roxlu/krx_rtc
int krx_ssl_ctx_init(krx* k, const char* keyname) {

  int r = 0;

  /* create a new context using DTLS */
  k->ctx = SSL_CTX_new(DTLSv1_method());
  if(!k->ctx) {
    printf("Error: cannot create SSL_CTX.\n");
    ERR_print_errors_fp(stderr);
    return -1;
  }

  /* set our supported ciphers */
  r = SSL_CTX_set_cipher_list(k->ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
  if(r != 1) {
    printf("Error: cannot set the cipher list.\n");
    ERR_print_errors_fp(stderr);
    return -2;
  }

  /* the client doesn't have to send it's certificate */
  SSL_CTX_set_verify(k->ctx, SSL_VERIFY_PEER, krx_ssl_verify_peer);

  /* enable srtp */
  r = SSL_CTX_set_tlsext_use_srtp(k->ctx, "SRTP_AES128_CM_SHA1_80");
  if(r != 0) {
    printf("Error: cannot setup srtp.\n");
    ERR_print_errors_fp(stderr);
    return -3;
  }

  /* load key and certificate */
  char certfile[1024];
  char keyfile[1024];
  sprintf(certfile, "./%s-cert.pem", keyname);
  sprintf(keyfile, "./%s-key.pem", keyname);

  /* certificate file; contains also the public key */
  r = SSL_CTX_use_certificate_file(k->ctx, certfile, SSL_FILETYPE_PEM);
  if(r != 1) {
    printf("Error: cannot load certificate file.\n");
    ERR_print_errors_fp(stderr);
    return -4;
  }

  /* load private key */
  r = SSL_CTX_use_PrivateKey_file(k->ctx, keyfile, SSL_FILETYPE_PEM);
  if(r != 1) {
    printf("Error: cannot load private key file.\n");
    ERR_print_errors_fp(stderr);
    return -5;
  }
  
  /* check if the private key is valid */
  r = SSL_CTX_check_private_key(k->ctx);
  if(r != 1) {
    printf("Error: checking the private key failed. \n");
    ERR_print_errors_fp(stderr);
    return -6;
  }

  sprintf(k->name, "+ %s", keyname);

  return 0;
}
示例#13
0
int main(int argc, char *argv[]) {
	BIO *sbio;
	SSL_CTX *ssl_ctx;
	SSL *ssl;
	X509 *server_cert;

	// Initialize OpenSSL
	OpenSSL_add_all_algorithms();
	SSL_library_init();
	SSL_load_error_strings();

 	// Check OpenSSL PRNG
	if(RAND_status() != 1) {
		fprintf(stderr, "OpenSSL PRNG not seeded with enough data.");
		goto error_1;
	}

	ssl_ctx = SSL_CTX_new(TLSv1_client_method());
	
	// Enable certificate validation
	SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
	// Configure the CA trust store to be used
	if (SSL_CTX_load_verify_locations(ssl_ctx, TRUSTED_CA_PATHNAME, NULL) != 1) {
		fprintf(stderr, "Couldn't load certificate trust store.\n");
		goto error_2;
	}

	// Only support secure cipher suites
	if (SSL_CTX_set_cipher_list(ssl_ctx, SECURE_CIPHER_LIST) != 1)
		goto error_2;

	// Create the SSL connection
	sbio = BIO_new_ssl_connect(ssl_ctx);
	BIO_get_ssl(sbio, &ssl); 
	if(!ssl) {
	  fprintf(stderr, "Can't locate SSL pointer\n");
		goto error_3;
	}

	// Do the SSL handshake
	BIO_set_conn_hostname(sbio, TARGET_SERVER);
	if(SSL_do_handshake(ssl) <= 0) {
		// SSL Handshake failed
		long verify_err = SSL_get_verify_result(ssl);
		if (verify_err != X509_V_OK) { 
			// It failed because the certificate chain validation failed
			fprintf(stderr, "Certificate chain validation failed: %s\n", X509_verify_cert_error_string(verify_err));
		}
		else {
			// It failed for another reason
			ERR_print_errors_fp(stderr);
		}
		goto error_3;
	}

	// Recover the server's certificate
	server_cert =  SSL_get_peer_certificate(ssl);
	if (server_cert == NULL) {
		// The handshake was successful although the server did not provide a certificate
		// Most likely using an insecure anonymous cipher suite... get out!
		goto error_4;
	}

	// Validate the hostname
	if (validate_hostname(TARGET_HOST, server_cert) != MatchFound) {
		fprintf(stderr, "Hostname validation failed.\n");
		goto error_5;
	}

	// Hostname validation succeeded; we can start sending data
	send_http_get_and_print(sbio);


error_5:
	X509_free(server_cert);

error_4:
	BIO_ssl_shutdown(sbio);

error_3:
	BIO_free_all(sbio);

error_2:
	SSL_CTX_free(ssl_ctx);

error_1: // OpenSSL cleanup
    EVP_cleanup();
    ERR_free_strings();

	return 0;
}
示例#14
0
static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
	{
	EC_KEY *a=NULL;
	EC_KEY *b=NULL;
	BIGNUM *x_a=NULL, *y_a=NULL,
	       *x_b=NULL, *y_b=NULL;
	char buf[12];
	unsigned char *abuf=NULL,*bbuf=NULL;
	int i,alen,blen,aout,bout,ret=0;
	const EC_GROUP *group;

	a = EC_KEY_new_by_curve_name(nid);
	b = EC_KEY_new_by_curve_name(nid);
	if (a == NULL || b == NULL)
		goto err;

	group = EC_KEY_get0_group(a);

	if ((x_a=BN_new()) == NULL) goto err;
	if ((y_a=BN_new()) == NULL) goto err;
	if ((x_b=BN_new()) == NULL) goto err;
	if ((y_b=BN_new()) == NULL) goto err;

	BIO_puts(out,"Testing key generation with ");
	BIO_puts(out,text);
#ifdef NOISY
	BIO_puts(out,"\n");
#else
	(void)BIO_flush(out);
#endif

	if (!EC_KEY_generate_key(a)) goto err;
	
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
		{
		if (!EC_POINT_get_affine_coordinates_GFp(group,
			EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
		}
	else
		{
		if (!EC_POINT_get_affine_coordinates_GF2m(group,
			EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
		}
#ifdef NOISY
	BIO_puts(out,"  pri 1=");
	BN_print(out,a->priv_key);
	BIO_puts(out,"\n  pub 1=");
	BN_print(out,x_a);
	BIO_puts(out,",");
	BN_print(out,y_a);
	BIO_puts(out,"\n");
#else
	BIO_printf(out," .");
	(void)BIO_flush(out);
#endif

	if (!EC_KEY_generate_key(b)) goto err;

	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) 
		{
		if (!EC_POINT_get_affine_coordinates_GFp(group, 
			EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
		}
	else
		{
		if (!EC_POINT_get_affine_coordinates_GF2m(group, 
			EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
		}

#ifdef NOISY
	BIO_puts(out,"  pri 2=");
	BN_print(out,b->priv_key);
	BIO_puts(out,"\n  pub 2=");
	BN_print(out,x_b);
	BIO_puts(out,",");
	BN_print(out,y_b);
	BIO_puts(out,"\n");
#else
	BIO_printf(out,".");
	(void)BIO_flush(out);
#endif

	alen=KDF1_SHA1_len;
	abuf=(unsigned char *)OPENSSL_malloc(alen);
	aout=ECDH_compute_key(abuf,alen,EC_KEY_get0_public_key(b),a,KDF1_SHA1);

#ifdef NOISY
	BIO_puts(out,"  key1 =");
	for (i=0; i<aout; i++)
		{
		TINYCLR_SSL_SPRINTF(buf,"%02X",abuf[i]);
		BIO_puts(out,buf);
		}
	BIO_puts(out,"\n");
#else
	BIO_printf(out,".");
	(void)BIO_flush(out);
#endif

	blen=KDF1_SHA1_len;
	bbuf=(unsigned char *)OPENSSL_malloc(blen);
	bout=ECDH_compute_key(bbuf,blen,EC_KEY_get0_public_key(a),b,KDF1_SHA1);

#ifdef NOISY
	BIO_puts(out,"  key2 =");
	for (i=0; i<bout; i++)
		{
		TINYCLR_SSL_SPRINTF(buf,"%02X",bbuf[i]);
		BIO_puts(out,buf);
		}
	BIO_puts(out,"\n");
#else
	BIO_printf(out,".");
	(void)BIO_flush(out);
#endif

	if ((aout < 4) || (bout != aout) || (TINYCLR_SSL_MEMCMP(abuf,bbuf,aout) != 0))
		{
#ifndef NOISY
		BIO_printf(out, " failed\n\n");
		BIO_printf(out, "key a:\n");
		BIO_printf(out, "private key: ");
		BN_print(out, EC_KEY_get0_private_key(a));
		BIO_printf(out, "\n");
		BIO_printf(out, "public key (x,y): ");
		BN_print(out, x_a);
		BIO_printf(out, ",");
		BN_print(out, y_a);
		BIO_printf(out, "\nkey b:\n");
		BIO_printf(out, "private key: ");
		BN_print(out, EC_KEY_get0_private_key(b));
		BIO_printf(out, "\n");
		BIO_printf(out, "public key (x,y): ");
		BN_print(out, x_b);
		BIO_printf(out, ",");
		BN_print(out, y_b);
		BIO_printf(out, "\n");
		BIO_printf(out, "generated key a: ");
		for (i=0; i<bout; i++)
			{
			TINYCLR_SSL_SPRINTF(buf, "%02X", bbuf[i]);
			BIO_puts(out, buf);
			}
		BIO_printf(out, "\n");
		BIO_printf(out, "generated key b: ");
		for (i=0; i<aout; i++)
			{
			TINYCLR_SSL_SPRINTF(buf, "%02X", abuf[i]);
			BIO_puts(out,buf);
			}
		BIO_printf(out, "\n");
#endif
		TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"Error in ECDH routines\n");
		ret=0;
		}
	else
		{
#ifndef NOISY
		BIO_printf(out, " ok\n");
#endif
		ret=1;
		}
err:
	ERR_print_errors_fp(OPENSSL_TYPE__FILE_STDERR);

	if (abuf != NULL) OPENSSL_free(abuf);
	if (bbuf != NULL) OPENSSL_free(bbuf);
	if (x_a) BN_free(x_a);
	if (y_a) BN_free(y_a);
	if (x_b) BN_free(x_b);
	if (y_b) BN_free(y_b);
	if (b) EC_KEY_free(b);
	if (a) EC_KEY_free(a);
	return(ret);
	}
示例#15
0
文件: common.c 项目: modsix/destroyd
void handle_error(const char *file, int linenum, const char *msg) {
	
	fprintf(stderr, "*** %s:%i %s\n", file, linenum, msg);
	ERR_print_errors_fp(stderr);
	exit(-1);
}
示例#16
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")) {
            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);
}
示例#17
0
void secure_and_send(int client_fd, char* read_pipe, char* write_pipe, int index, FILE* d_out){
	BIO* bio;
	SSL* ssl;
	SSL_CTX* ctx;
	
	/*init ssl library*/
	SSL_library_init();
	ERR_load_BIO_strings();
	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();
	
	/* Set up the SSL context */

    ctx = SSL_CTX_new(SSLv23_client_method());

    /* Load the trust store */

    if(! SSL_CTX_load_verify_locations(ctx, "cacerts.pem", NULL))
    {
        fprintf(stderr, "Error loading trust store\n");
        ERR_print_errors_fp(stderr);
        SSL_CTX_free(ctx);
        return;
    }
    /* Setup the connection */

    bio = BIO_new_ssl_connect(ctx);

    /* Set the SSL_MODE_AUTO_RETRY flag */

    BIO_get_ssl(bio, & ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    
    /* Create and setup the connection */
	char host[LINE];
	sprintf(host,"%s:%s",safe_host[index],safe_port[index]);
    BIO_set_conn_hostname(bio, safe_host[index]);
    BIO_set_conn_port(bio,safe_port[index]);

    if(BIO_do_connect(bio) <= 0)
    {
        fprintf(stderr, "Error attempting to connect\n");
        ERR_print_errors_fp(stderr);
        BIO_free_all(bio);
        SSL_CTX_free(ctx);
        return;
    }

    /* Check the certificate */

    if(SSL_get_verify_result(ssl) != X509_V_OK)
    {
        fprintf(stderr, "Certificate verification error: %lu\n", SSL_get_verify_result(ssl));
        BIO_free_all(bio);
        SSL_CTX_free(ctx);
        return;
    }
    /* Send the request */

    BIO_write(bio, read_pipe, strlen(read_pipe));

    /* Read in the response */

    for(;;)
    {
        int p = BIO_read(bio, write_pipe, PIPE_MAX);
        if(p <= 0) break;
        p = write(client_fd,write_pipe,p);
    }

    /* Close the connection and free the context */
	
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    close(client_fd);
    fclose(d_out);
    return;
}
示例#18
0
void handleErrors(void)
{
  ERR_print_errors_fp(stderr);
  abort();
}
示例#19
0
int main(int argc, char **argv)
{
    FILE *fp;
    // Bucket to keep pids in.
    int process_pool[POOL_SIZE];
    // Count of pids we are wait()ing on.
    int c = 0, test_config = 0, use_ip_address = 0, pid = 0, status, i = 0, active_processes = 0;
    int gid = 0, client_sock = 0, sock = 0, port = DEFAULT_PORT, ret = 0;
    char *dir  = DEFAULTDIR;
    char *group = GROUPGLOBAL;
    char *server_cert = NULL;
    char *server_key = NULL;
    char *ca_cert = NULL;
    char buf[4096 +1];
    SSL_CTX *ctx;
    SSL *ssl;
    char srcip[IPSIZE +1];
    struct sockaddr_in _nc;
    socklen_t _ncl;


    /* Initializing some variables */
    memset(srcip, '\0', IPSIZE + 1);
    memset(process_pool, 0x0, POOL_SIZE);

    bio_err = 0;


    /* Setting the name */
    OS_SetName(ARGV0);
    /* add an option to use the ip on the socket to tie the name to a
       specific address */
    while((c = getopt(argc, argv, "Vdhtig:D:m:p:v:x:k:")) != -1)
    {
        switch(c){
            case 'V':
                print_version();
                break;
            case 'h':
                help_authd();
                break;
            case 'd':
                nowDebug();
                break;
            case 'i':
                use_ip_address = 1;
                break;
            case 'g':
                if(!optarg)
                    ErrorExit("%s: -g needs an argument",ARGV0);
                group = optarg;
                break;
            case 'D':
                if(!optarg)
                    ErrorExit("%s: -D needs an argument",ARGV0);
                dir = optarg;
                break;
            case 't':
                test_config = 1;
                break;
            case 'p':
               if(!optarg)
                    ErrorExit("%s: -%c needs an argument",ARGV0, c);
                port = atoi(optarg);
                if(port <= 0 || port >= 65536)
                {
                    ErrorExit("%s: Invalid port: %s", ARGV0, optarg);
                }
                break;
            case 'v':
                if (!optarg)
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                ca_cert = optarg;
                break;
            case 'x':
                if (!optarg)
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                server_cert = optarg;
                break;
            case 'k':
                if (!optarg)
                    ErrorExit("%s: -%c needs an argument", ARGV0, c);
                server_key = optarg;
                break;
            default:
                help_authd();
                break;
        }

    }

    /* Starting daemon -- NB: need to double fork and setsid */
    debug1(STARTED_MSG,ARGV0);

    /* Check if the user/group given are valid */
    gid = Privsep_GetGroup(group);
    if(gid < 0)
        ErrorExit(USER_ERROR,ARGV0,"",group);


    /* Exit here if test config is set */
    if(test_config)
        exit(0);


    /* Privilege separation */
    if(Privsep_SetGroup(gid) < 0)
        ErrorExit(SETGID_ERROR,ARGV0,group);


    /* chrooting -- TODO: this isn't a chroot. Should also close
       unneeded open file descriptors (like stdin/stdout)*/
    if(chdir(dir) == -1)
    {
        ErrorExit(CHDIR_ERROR, ARGV0, dir);
    }



    /* Signal manipulation */
    StartSIG(ARGV0);


    /* Creating PID files */
    if(CreatePID(ARGV0, getpid()) < 0)
        ErrorExit(PID_ERROR,ARGV0);

    /* Start up message */
    verbose(STARTUP_MSG, ARGV0, (int)getpid());


    fp = fopen(KEYSFILE_PATH,"a");
    if(!fp)
    {
        merror("%s: ERROR: Unable to open %s (key file)", ARGV0, KEYSFILE_PATH);
        exit(1);
    }


    /* Starting SSL */
    ctx = os_ssl_keys(1, dir, server_cert, server_key, ca_cert);
    if(!ctx)
    {
        merror("%s: ERROR: SSL error. Exiting.", ARGV0);
        exit(1);
    }


    /* Connecting via TCP */
    sock = OS_Bindporttcp(port, NULL, 0);
    if(sock <= 0)
    {
        merror("%s: Unable to bind to port %d", ARGV0, port);
        exit(1);
    }
    fcntl(sock, F_SETFL, O_NONBLOCK);

    debug1("%s: DEBUG: Going into listening mode.", ARGV0);
    while(1)
    {

        // no need to completely pin the cpu, 100ms should be fast enough
        usleep(100*1000);

        // Only check process-pool if we have active processes
        if(active_processes > 0){
            for (i = 0; i < POOL_SIZE; i++)
            {
                int rv = 0;
                status = 0;
                if (process_pool[i])
                {
                    rv = waitpid(process_pool[i], &status, WNOHANG);
                    if (rv != 0){
                        debug1("%s: DEBUG: Process %d exited", ARGV0, process_pool[i]);
                        process_pool[i] = 0;
                        active_processes = active_processes - 1;
                    }
                }
            }
        }
        memset(&_nc, 0, sizeof(_nc));
        _ncl = sizeof(_nc);

        if((client_sock = accept(sock, (struct sockaddr *) &_nc, &_ncl)) > 0){
            if (active_processes >= POOL_SIZE)
            {
                merror("%s: Error: Max concurrency reached. Unable to fork", ARGV0);
                break;
            }
            pid = fork();
            if(pid)
            {
                active_processes = active_processes + 1;
                close(client_sock);
                for (i = 0; i < POOL_SIZE; i++)
                {
                    if (! process_pool[i])
                    {
                        process_pool[i] = pid;
                        break;
                    }
                }
            }
            else
            {
                strncpy(srcip, inet_ntoa(_nc.sin_addr),IPSIZE -1);
                char *agentname = NULL;
                ssl = SSL_new(ctx);
                SSL_set_fd(ssl, client_sock);

                do
                {
                    ret = SSL_accept(ssl);

                    if (ssl_error(ssl, ret))
                        clean_exit(ctx, client_sock);

                } while (ret <= 0);

                verbose("%s: INFO: New connection from %s", ARGV0, srcip);

                do
                {
                    ret = SSL_read(ssl, buf, sizeof(buf));

                    if (ssl_error(ssl, ret))
                        clean_exit(ctx, client_sock);

                } while (ret <= 0);

                int parseok = 0;
                if(strncmp(buf, "OSSEC A:'", 9) == 0)
                {
                    char *tmpstr = buf;
                    agentname = tmpstr + 9;
                    tmpstr += 9;
                    while(*tmpstr != '\0')
                    {
                        if(*tmpstr == '\'')
                        {
                            *tmpstr = '\0';
                            verbose("%s: INFO: Received request for a new agent (%s) from: %s", ARGV0, agentname, srcip);
                            parseok = 1;
                            break;
                        }
                        tmpstr++;
                    }
                }
                if(parseok == 0)
                {
                    merror("%s: ERROR: Invalid request for new agent from: %s", ARGV0, srcip);
                }
                else
                {
                    int acount = 2;
                    char fname[2048 +1];
                    char response[2048 +1];
                    char *finalkey = NULL;
                    response[2048] = '\0';
                    fname[2048] = '\0';
                    if(!OS_IsValidName(agentname))
                    {
                        merror("%s: ERROR: Invalid agent name: %s from %s", ARGV0, agentname, srcip);
                        snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname);
                        ret = SSL_write(ssl, response, strlen(response));
                        snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                        ret = SSL_write(ssl, response, strlen(response));
                        sleep(1);
                        exit(0);
                    }


                    /* Checking for a duplicated names. */
                    strncpy(fname, agentname, 2048);
                    while(NameExist(fname))
                    {
                        snprintf(fname, 2048, "%s%d", agentname, acount);
                        acount++;
                        if(acount > 256)
                        {
                            merror("%s: ERROR: Invalid agent name %s (duplicated)", ARGV0, agentname);
                            snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname);
                            ret = SSL_write(ssl, response, strlen(response));
                            snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                            ret = SSL_write(ssl, response, strlen(response));
                            sleep(1);
                            exit(0);
                        }
                    }
                    agentname = fname;


                    /* Adding the new agent. */
                    if (use_ip_address)
                    {
                        finalkey = OS_AddNewAgent(agentname, srcip, NULL);
                    }
                    else
                    {
                        finalkey = OS_AddNewAgent(agentname, NULL, NULL);
                    }
                    if(!finalkey)
                    {
                        merror("%s: ERROR: Unable to add agent: %s (internal error)", ARGV0, agentname);
                        snprintf(response, 2048, "ERROR: Internal manager error adding agent: %s\n\n", agentname);
                        ret = SSL_write(ssl, response, strlen(response));
                        snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
                        ret = SSL_write(ssl, response, strlen(response));
                        sleep(1);
                        exit(0);
                    }


                    snprintf(response, 2048,"OSSEC K:'%s'\n\n", finalkey);
                    verbose("%s: INFO: Agent key generated for %s (requested by %s)", ARGV0, agentname, srcip);
                    ret = SSL_write(ssl, response, strlen(response));
                    if(ret < 0)
                    {
                        merror("%s: ERROR: SSL write error (%d)", ARGV0, ret);
                        merror("%s: ERROR: Agen key not saved for %s", ARGV0, agentname);
                        ERR_print_errors_fp(stderr);
                    }
                    else
                    {
                        verbose("%s: INFO: Agent key created for %s (requested by %s)", ARGV0, agentname, srcip);
                    }
                }

                clean_exit(ctx, client_sock);
            }
        }
    }


    /* Shutdown the socket */
    clean_exit(ctx, sock);

    return (0);
}
示例#20
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);
}
示例#21
0
/**
 * \brief Input plugin initializtion function
 *
 * \param[in]  params  XML with input parameters
 * \param[out] config  Sets source and destination IP, destination port.
 * \return 0 on success, nonzero else.
 */
int input_init(char *params, void **config)
{
	/* necessary structures */
	struct addrinfo *addrinfo = NULL, hints;
	struct plugin_conf *conf = NULL;
	char *port = NULL, *address = NULL;
	int ai_family = AF_INET6; /* IPv6 is default */
	char dst_addr[INET6_ADDRSTRLEN];
	int ret, ipv6_only = 0, retval = 0, yes = 1; /* yes is for setsockopt */
	/* 1 when using default port - don't free memory */
	int def_port = 0;
#ifdef TLS_SUPPORT
	SSL_CTX *ctx = NULL;       /* SSL context structure */
	SSL **ssl_list = NULL;     /* list of SSL connection structures */
	xmlNode *cur_node_parent;
#endif

	/* parse params */
	xmlDoc *doc = NULL;
	xmlNode *root_element = NULL;
	xmlNode *cur_node = NULL;

	/* allocate plugin_conf structure */
	conf = calloc(1, sizeof(struct plugin_conf));
	if (conf == NULL) {
		MSG_ERROR(msg_module, "Cannot allocate memory for config structure: %s", strerror(errno));
		retval = 1;
		goto out;
	}

	if (!enlarge_sock_addresses(conf)) {
		MSG_ERROR(msg_module, "Cannot initialize array for socket address");
		retval = 1;
		goto out;
	}

	/* empty the master set */
	FD_ZERO(&conf->master);

	/* parse xml string */
	doc = xmlParseDoc(BAD_CAST params);
	if (doc == NULL) {
		MSG_ERROR(msg_module, "Cannot parse configuration file");
		retval = 1;
		goto out;
	}
	/* get the root element node */
	root_element = xmlDocGetRootElement(doc);
	if (root_element == NULL) {
		MSG_ERROR(msg_module, "Cannot get document root element");
		retval = 1;
		goto out;
	}

	/* check that we have the right config xml, BAD_CAST is (xmlChar *) cast defined by libxml */
	if (!xmlStrEqual(root_element->name, BAD_CAST "tcpCollector")) {
		MSG_ERROR(msg_module, "Expecting tcpCollector root element; got %s", root_element->name);
		retval = 1;
		goto out;
	}

	/* go over all elements */
	for (cur_node = root_element->children; cur_node; cur_node = cur_node->next) {
#ifdef TLS_SUPPORT
		/* check whether we want to enable transport layer security */
		if (xmlStrEqual(cur_node->name, BAD_CAST "transportLayerSecurity")) {
			MSG_INFO(msg_module, "TLS enabled");
			conf->tls = 1;   /* TLS enabled */
			cur_node_parent = cur_node;	

			/* TLS configuration options */
			for (cur_node = cur_node->xmlChildrenNode; cur_node; cur_node = cur_node->next) {
			if (cur_node->type == XML_ELEMENT_NODE
						&& cur_node->children != NULL
						&& cur_node->children->content != NULL) {
					int tmp_val_len = strlen((char *) cur_node->children->content) + 1;
					char *tmp_val = malloc(sizeof(char) * tmp_val_len);
					if (!tmp_val) {
						MSG_ERROR(msg_module, "Cannot allocate memory: %s", strerror(errno));
						retval = 1;
						goto out;
					}
					strncpy_safe(tmp_val, (char *)cur_node->children->content, tmp_val_len);
					
					if (xmlStrEqual(cur_node->name, BAD_CAST "localCAfile")) {
						/* location of the CA certificate */
						conf->ca_cert_file = tmp_val;
					} else if (xmlStrEqual(cur_node->name, BAD_CAST "localServerCert")) {
						/* server's certificate */
						conf->server_cert_file = tmp_val;
					} else if (xmlStrEqual(cur_node->name, BAD_CAST "localServerCertKey")) {
						/* server's private key */
						conf->server_pkey_file = tmp_val;
					} else {
						/* unknown option */
						MSG_WARNING(msg_module, "Unknown configuration option: %s", cur_node->name);
						free(tmp_val);
					}
				}
			}

			cur_node = cur_node_parent;

			continue;
		}
#else   /* user wants TLS, but collector was compiled without it */
		if (xmlStrEqual(cur_node->name, BAD_CAST "transportLayerSecurity")) {
			/* user wants to enable TLS, but collector was compiled without it */
			MSG_WARNING(msg_module, "Collector was compiled without TLS support");
			continue;
		}
#endif
		if (cur_node->type == XML_ELEMENT_NODE && cur_node->children != NULL) {
			/* copy value to memory - don't forget the terminating zero */
			int tmp_val_len = strlen((char *) cur_node->children->content) + 1;
			char *tmp_val = malloc(sizeof(char) * tmp_val_len);
			/* this is not a preferred cast, but we really want to use plain chars here */
			if (tmp_val == NULL) {
				MSG_ERROR(msg_module, "Cannot allocate memory: %s", strerror(errno));
				retval = 1;
				goto out;
			}
			strncpy_safe(tmp_val, (char *)cur_node->children->content, tmp_val_len);

			if (xmlStrEqual(cur_node->name, BAD_CAST "localPort") && port == NULL) { /* set local port */
				port = tmp_val;
			} else if (xmlStrEqual(cur_node->name, BAD_CAST "localIPAddress") && address == NULL) { /* set local address */
				address = tmp_val;
			/* save following configuration to input_info */
			} else if (xmlStrEqual(cur_node->name, BAD_CAST "templateLifeTime")) {
				conf->info.template_life_time = tmp_val;
			} else if (xmlStrEqual(cur_node->name, BAD_CAST "optionsTemplateLifeTime")) {
				conf->info.options_template_life_time = tmp_val;
			} else if (xmlStrEqual(cur_node->name, BAD_CAST "templateLifePacket")) {
				conf->info.template_life_packet = tmp_val;
			} else if (xmlStrEqual(cur_node->name, BAD_CAST "optionsTemplateLifePacket")) {
				conf->info.options_template_life_packet = tmp_val;
			} else { /* unknown parameter, ignore */
				/* Free the tmp_val for unknown elements */
				free(tmp_val);
			}
		}
	}

	/* set default port if none given */
	if (port == NULL) {
		port = DEFAULT_PORT;
		def_port = 1;
	}

#ifdef TLS_SUPPORT
	if (conf->tls) {
		/* use default options if not specified in configuration file */
		if (conf->ca_cert_file == NULL) {
			conf->ca_cert_file = strdup(DEFAULT_CA_FILE);
		}

		if (conf->server_cert_file == NULL) {
			conf->server_cert_file = strdup(DEFAULT_SERVER_CERT_FILE);
		}

		if (conf->server_pkey_file == NULL) {
			conf->server_pkey_file = strdup(DEFAULT_SERVER_PKEY_FILE);
		}
	}
#endif

	/* specify parameters of the connection */
	memset (&hints, 0, sizeof(struct addrinfo));
	hints.ai_socktype = SOCK_STREAM; /* TCP */
	hints.ai_family = ai_family; /* select IPv4 or IPv6*/
	hints.ai_flags = AI_V4MAPPED; /* we want to accept mapped addresses */
	if (address == NULL) {
		hints.ai_flags |= AI_PASSIVE; /* no address given, listen on all local addresses */
	}

	/* get server address */
	if ((ret = getaddrinfo(address, port, &hints, &addrinfo)) != 0) {
		MSG_ERROR(msg_module, "getaddrinfo failed: %s", gai_strerror(ret));
		retval = 1;
		goto out;
	}

	/* create socket */
	conf->socket = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol);
	/* Retry with IPv4 when the implementation does not support the specified address family */
	if (conf->socket == -1 && errno == EAFNOSUPPORT && addrinfo->ai_family == AF_INET6) {
		addrinfo->ai_family = AF_INET;
		conf->socket = socket(addrinfo->ai_family, addrinfo->ai_socktype, addrinfo->ai_protocol);
	}
	if (conf->socket == -1) {
		/* End with error otherwise */
		MSG_ERROR(msg_module, "Cannot create socket: %s", strerror(errno));
		retval = 1;
		goto out;
	}

	/* allow IPv4 connections on IPv6 */
	if ((addrinfo->ai_family == AF_INET6) &&
		(setsockopt(conf->socket, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6_only, sizeof(ipv6_only)) == -1)) {
		MSG_WARNING(msg_module, "Cannot turn off socket option IPV6_V6ONLY; plugin may not accept IPv4 connections...");
	}

	/* allow to reuse the address immediately */
	if (setsockopt(conf->socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1)
	{
		MSG_WARNING(msg_module, "Cannot turn on socket reuse option; it may take a while before collector can be restarted");
	}

	/* bind socket to address */
	if (bind(conf->socket, addrinfo->ai_addr, addrinfo->ai_addrlen) != 0) {
		MSG_ERROR(msg_module, "Cannot bind socket: %s", strerror(errno));
		retval = 1;
		goto out;
	}

	/* this is a listening socket */
	if (listen(conf->socket, BACKLOG) == -1) {
		MSG_ERROR(msg_module, "Cannot listen on socket: %s", strerror(errno));
		retval = 1;
		goto out;
	}

#ifdef TLS_SUPPORT
	if (conf->tls) {
		/* configure TLS */
	
		/* initialize library */
		SSL_load_error_strings();
		SSL_library_init();
	
		/* create CTX structure for TLS */
		ctx = SSL_CTX_new(TLSv1_server_method());
		if (!ctx) {
			MSG_ERROR(msg_module, "Cannot create CTX structure");
			ERR_print_errors_fp(stderr);
			retval = 1;
			goto out;
		}
	
		/* load server certificate into the CTX structure */
		ret = SSL_CTX_use_certificate_file(ctx, conf->server_cert_file, SSL_FILETYPE_PEM);
		if (ret != 1) {
			MSG_ERROR(msg_module, "Unable to load server's certificate from %s", conf->server_cert_file);
			ERR_print_errors_fp(stderr);
			retval = 1;
			goto out;
		}
	
		/* load private keys into the CTX structure */
		SSL_CTX_use_PrivateKey_file(ctx, conf->server_pkey_file, SSL_FILETYPE_PEM);
		if (ret <= 0) {
			MSG_ERROR(msg_module, "Unable to load server's private key from %s", conf->server_pkey_file);
			ERR_print_errors_fp(stderr);
			retval = 1;
			goto out;
		}

		/* set peer certificate verification parameters */
		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);
		
		ssl_list = (SSL **) malloc(sizeof(SSL *) * DEFAULT_SIZE_SSL_LIST);
		if (ssl_list == NULL) {
			MSG_ERROR(msg_module, "Memory allocation failed (%s:%d)", __FILE__, __LINE__);
			retval = 1;
			goto out;
		}
		memset(ssl_list, 0, DEFAULT_SIZE_SSL_LIST * sizeof(SSL *));

		conf->ssl_list_size = DEFAULT_SIZE_SSL_LIST;
		conf->ctx = ctx;
		conf->ssl_list = ssl_list;
	}
#endif  /* TLS */

	/* fill in general information */
	conf->info.type = SOURCE_TYPE_TCP;
	conf->info.dst_port = atoi(port);
	if (addrinfo->ai_family == AF_INET) { /* IPv4 */
		conf->info.l3_proto = 4;

		/* copy dst IPv4 address */
		conf->info.dst_addr.ipv4.s_addr =
			((struct sockaddr_in*) addrinfo->ai_addr)->sin_addr.s_addr;

		inet_ntop(AF_INET, &conf->info.dst_addr.ipv4, dst_addr, INET6_ADDRSTRLEN);
	} else { /* IPv6 */
		conf->info.l3_proto = 6;

		/* copy dst IPv6 address */
		int i;
		for (i=0; i<4;i++) {
			conf->info.dst_addr.ipv6.s6_addr32[i] =
				((struct sockaddr_in6*) addrinfo->ai_addr)->sin6_addr.s6_addr32[i];
		}

		inet_ntop(AF_INET6, &conf->info.dst_addr.ipv6, dst_addr, INET6_ADDRSTRLEN);
	}

	/* allocate memory for templates */
	if (convert_init(TCP_PLUGIN, BUFF_LEN) != 0) {
		MSG_ERROR(msg_module, "malloc() for templates failed!");
		retval = 1;
		goto out;
	}

	/* print info */
	MSG_INFO(msg_module, "Input plugin listening on %s, port %s", dst_addr, port);

	/* start listening thread */
	if (pthread_create(&listen_thread, NULL, &input_listen, (void *) conf) != 0) {
		MSG_ERROR(msg_module, "Failed to create listening thread");
		retval = 1;
		goto out;
	}

	/* pass general information to the collector */
	*config = (void*) conf;

	/* normal exit, all OK */
	MSG_INFO(msg_module, "Plugin initialization completed successfully");

out:
	if (def_port == 0 && port != NULL) { /* free when memory was actually allocated*/
		free(port);
	}

	if (address != NULL) {
		free(address);
	}

	if (addrinfo != NULL) {
		freeaddrinfo(addrinfo);
	}

	/* free the xml document */
	if (doc != NULL) {
		xmlFreeDoc(doc);
	}

	/* free the global variables that may have been allocated by the xml parser */
	xmlCleanupParser();

	/* free input_info when error occured */
	if (retval != 0 && conf != NULL) {
		if (conf->info.template_life_time != NULL) {
			free (conf->info.template_life_time);
		}
		if (conf->info.options_template_life_time != NULL) {
			free (conf->info.options_template_life_time);
		}
		if (conf->info.template_life_packet != NULL) {
			free (conf->info.template_life_packet);
		}
		if (conf->info.options_template_life_packet != NULL) {
			free (conf->info.options_template_life_packet);
		}
		free(conf);

	}

#ifdef TLS_SUPPORT
	/* error occurs, clean up */
	if ((retval != 0) && (conf != NULL)) {
		if (ssl_list) {
			free(ssl_list);
		}

		if (ctx) {
			SSL_CTX_free(ctx);
		}
	}
#endif

	return retval;
}
示例#22
0
int main(int argc, char **argv)
{
    BIO *sbio = NULL, *out = NULL;
    int i, len, rv;
    char tmpbuf[1024];
    SSL_CTX *ctx = NULL;
    SSL_CONF_CTX *cctx = NULL;
    SSL *ssl = NULL;
    CONF *conf = NULL;
    STACK_OF(CONF_VALUE) *sect = NULL;
    CONF_VALUE *cnf;
    const char *connect_str = "localhost:4433";
    long errline = -1;

    ERR_load_crypto_strings();
    ERR_load_SSL_strings();
    SSL_library_init();

    conf = NCONF_new(NULL);

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

    sect = NCONF_get_section(conf, "default");

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

    ctx = SSL_CTX_new(TLS_client_method());
    cctx = SSL_CONF_CTX_new();
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
    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++) {
        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 end;
        }
        if (strcmp(cnf->name, "Connect") == 0) {
            connect_str = cnf->value;
        } else {
            fprintf(stderr, "Unknown configuration option %s\n", cnf->name);
            goto end;
        }
    }

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

    /*
     * We'd normally set some stuff like the verify paths and * mode here
     * because as things stand this will connect to * any server whose
     * certificate is signed by any CA.
     */

    sbio = BIO_new_ssl_connect(ctx);

    BIO_get_ssl(sbio, &ssl);

    if (!ssl) {
        fprintf(stderr, "Can't locate SSL pointer\n");
        goto end;
    }

    /* Don't want any retries */
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    /* We might want to do other things with ssl here */

    BIO_set_conn_hostname(sbio, connect_str);

    out = BIO_new_fp(stdout, BIO_NOCLOSE);
    if (BIO_do_connect(sbio) <= 0) {
        fprintf(stderr, "Error connecting to server\n");
        ERR_print_errors_fp(stderr);
        goto end;
    }

    if (BIO_do_handshake(sbio) <= 0) {
        fprintf(stderr, "Error establishing SSL connection\n");
        ERR_print_errors_fp(stderr);
        goto end;
    }

    /* Could examine ssl here to get connection info */

    BIO_puts(sbio, "GET / HTTP/1.0\n\n");
    for (;;) {
        len = BIO_read(sbio, tmpbuf, 1024);
        if (len <= 0)
            break;
        BIO_write(out, tmpbuf, len);
    }
 end:
    SSL_CONF_CTX_free(cctx);
    BIO_free_all(sbio);
    BIO_free(out);
    NCONF_free(conf);
    return 0;
}
示例#23
0
文件: dhtest.c 项目: Henauxg/minix
int main(int argc, char *argv[])
{
    BN_GENCB _cb;
    DH *a;
    DH *b = NULL;
    char buf[12];
    unsigned char *abuf = NULL, *bbuf = NULL;
    int i, alen, blen, aout, bout, ret = 1;
    BIO *out;

    CRYPTO_malloc_debug_init();
    CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

# ifdef OPENSSL_SYS_WIN32
    CRYPTO_malloc_init();
# endif

    RAND_seed(rnd_seed, sizeof rnd_seed);

    out = BIO_new(BIO_s_file());
    if (out == NULL)
        EXIT(1);
    BIO_set_fp(out, stdout, BIO_NOCLOSE);

    BN_GENCB_set(&_cb, &cb, out);
    if (((a = DH_new()) == NULL) || !DH_generate_parameters_ex(a, 64,
                                                               DH_GENERATOR_5,
                                                               &_cb))
        goto err;

    if (!DH_check(a, &i))
        goto err;
    if (i & DH_CHECK_P_NOT_PRIME)
        BIO_puts(out, "p value is not prime\n");
    if (i & DH_CHECK_P_NOT_SAFE_PRIME)
        BIO_puts(out, "p value is not a safe prime\n");
    if (i & DH_UNABLE_TO_CHECK_GENERATOR)
        BIO_puts(out, "unable to check the generator value\n");
    if (i & DH_NOT_SUITABLE_GENERATOR)
        BIO_puts(out, "the g value is not a generator\n");

    BIO_puts(out, "\np    =");
    BN_print(out, a->p);
    BIO_puts(out, "\ng    =");
    BN_print(out, a->g);
    BIO_puts(out, "\n");

    b = DH_new();
    if (b == NULL)
        goto err;

    b->p = BN_dup(a->p);
    b->g = BN_dup(a->g);
    if ((b->p == NULL) || (b->g == NULL))
        goto err;

    /* Set a to run with normal modexp and b to use constant time */
    a->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
    b->flags |= DH_FLAG_NO_EXP_CONSTTIME;

    if (!DH_generate_key(a))
        goto err;
    BIO_puts(out, "pri 1=");
    BN_print(out, a->priv_key);
    BIO_puts(out, "\npub 1=");
    BN_print(out, a->pub_key);
    BIO_puts(out, "\n");

    if (!DH_generate_key(b))
        goto err;
    BIO_puts(out, "pri 2=");
    BN_print(out, b->priv_key);
    BIO_puts(out, "\npub 2=");
    BN_print(out, b->pub_key);
    BIO_puts(out, "\n");

    alen = DH_size(a);
    abuf = (unsigned char *)OPENSSL_malloc(alen);
    aout = DH_compute_key(abuf, b->pub_key, a);

    BIO_puts(out, "key1 =");
    for (i = 0; i < aout; i++) {
        snprintf(buf, sizeof(buf), "%02X",abuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");

    blen = DH_size(b);
    bbuf = (unsigned char *)OPENSSL_malloc(blen);
    bout = DH_compute_key(bbuf, a->pub_key, b);

    BIO_puts(out, "key2 =");
    for (i = 0; i < bout; i++) {
        snprintf(buf, sizeof(buf), "%02X",bbuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");
    if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) {
        fprintf(stderr, "Error in DH routines\n");
        ret = 1;
    } else
        ret = 0;
 err:
    ERR_print_errors_fp(stderr);

    if (abuf != NULL)
        OPENSSL_free(abuf);
    if (bbuf != NULL)
        OPENSSL_free(bbuf);
    if (b != NULL)
        DH_free(b);
    if (a != NULL)
        DH_free(a);
    BIO_free(out);
# ifdef OPENSSL_SYS_NETWARE
    if (ret)
        printf("ERROR: %d\n", ret);
# endif
    EXIT(ret);
    return (ret);
}
int main(int count, char *strings[])
{   
	SSL_CTX *ctx;
    int server;
    int choice=0;
    SSL *ssl;
    char buf[1024];
    int bytes;
    char *hostname, *portnum;
    char filename[20] ;

    if ( count != 3 ){
        printf("usage: %s <hostname> <portnum>\n", strings[0]);
        exit(0);
    }
    
    SSL_library_init();
    hostname=strings[1];
    portnum=strings[2];

    ctx = InitCTX();
    server = OpenConnection(hostname, atoi(portnum));
    ssl = SSL_new(ctx);      /* create new SSL connection state */
    SSL_set_fd(ssl, server);    /* attach the socket descriptor */
    if ( SSL_connect(ssl) == FAIL )   /* perform the connection */
        ERR_print_errors_fp(stderr);
    else{

        printf("Connected with %s encryption\n\n", SSL_get_cipher(ssl));
        ShowCerts(ssl);        /* get any certs */
        printf("\n\n");
        printf("Welcome to Cloud Storage System :\n Enter 1 - FILE UPLOAD\n 2 - FILE DOWNLOAD \n ");
     	scanf("%d",&choice);

        if(choice ==1){
			printf("Enter the file name you want to upload :");
			scanf("    %s",filename);
			FILE *fp = fopen(filename,"r");
			if(fp==NULL){
				printf("File open error\n\n");
				SSL_free(ssl);
				 close(server);         /* close socket */
				 SSL_CTX_free(ctx);
				return 1;
			}

			SSL_write(ssl,filename,sizeof(filename));
			char ack[10];
			SSL_read(ssl,ack,sizeof(ack));
       	    printf("File name ACK received: %s\n\n",ack);
       	     /* Read data from file and send it. First read file in chunks of BUF_SIZE bytes */
            unsigned char buff[BUF_SIZE]={0};
            int nread = fread(buff,1,BUF_SIZE,fp);
            printf("Bytes read %d \n", nread);

            /* If read was success, send data. */
            if(nread > 0){
				printf("Sending File contents to server Side \n");
				SSL_write(ssl, buff, nread);  /* send file contents to server */
        		calHmac(buff,filename,choice);
            }
			
			// SSL_write(ssl, msg, strlen(msg));
 			bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */
 			buf[bytes] = 0;
            printf("\nReceived: File Created at Server \n" );
        }
            
        else if(choice ==2){
            printf("Enter the file name you want to download :");
            scanf("    %s",filename);
            SSL_write(ssl,"DOWNLOAD",sizeof(filename));
            char ack[30];
            int replay=0;
            SSL_read(ssl,ack,sizeof(ack));
            printf("File name ACK received: %s\n\n",ack);
            strcat(ack,"-");
            strcat(ack,filename);
            printf("Do you want to try Replay Attack? If yes, enter 1:");
            scanf("%d",&replay);
            
            if(replay ==1){
            	printf("Enter the data to replay :");
            	scanf("%s",ack);
            	SSL_write(ssl,ack,sizeof(ack));
            }
            else{
           	SSL_write(ssl,ack,sizeof(ack));
            }
            
            unsigned char fileContent[256];
  			SSL_read(ssl,fileContent,sizeof(fileContent));
            printf("File Contents received: %s\n\n",fileContent);
            calHmac(fileContent,filename,choice);
            
            //path where downloaded files are stored
            char filepath[90]="/Users/prashanth/Desktop/try-1/ProejectTry-2/Download/";
            	            strcat(filepath,filename);
            	            FILE *DownloadFp=0;

            	            //writing Downloaded file contents to a new location
            	            DownloadFp = fopen(filepath, "w");
            	            if(DownloadFp == NULL)
            	                printf("Sorry, file cannot be created\n");
            	            else{
            	                fwrite(fileContent,sizeof(unsigned char), sizeof(fileContent),DownloadFp);
            	                printf("\n Path of Downloaded file:%s \n",filepath);
            	                fclose(DownloadFp);
            	                } // Directory al

        }
        
        else{
        	printf("Invalid Choice\n");
        	exit(0);
        }
        
        SSL_free(ssl);        /* release connection state */
    }
    close(server);         /* close socket */
    SSL_CTX_free(ctx);        /* release context */
    return 0;
}
示例#25
0
int test_mod_mul(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM *a,*b,*c,*d,*e;
	int i,j;

	a=BN_new();
	b=BN_new();
	c=BN_new();
	d=BN_new();
	e=BN_new();

	for (j=0; j<3; j++) {
	BN_bntest_rand(c,1024,0,0); /**/
	for (i=0; i<num0; i++)
		{
		BN_bntest_rand(a,475+i*10,0,0); /**/
		BN_bntest_rand(b,425+i*11,0,0); /**/
		a->neg=rand_neg();
		b->neg=rand_neg();
		if (!BN_mod_mul(e,a,b,c,ctx))
			{
			unsigned long l;

			while ((l=ERR_get_error()))
				fprintf(stderr,"ERROR:%s\n",
					ERR_error_string(l,NULL));
			EXIT(1);
			}
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," * ");
				BN_print(bp,b);
				BIO_puts(bp," % ");
				BN_print(bp,c);
				if ((a->neg ^ b->neg) && !BN_is_zero(e))
					{
					/* If  (a*b) % c  is negative,  c  must be added
					 * in order to obtain the normalized remainder
					 * (new with OpenSSL 0.9.7, previous versions of
					 * BN_mod_mul could generate negative results)
					 */
					BIO_puts(bp," + ");
					BN_print(bp,c);
					}
				BIO_puts(bp," - ");
				}
			BN_print(bp,e);
			BIO_puts(bp,"\n");
			}
		BN_mul(d,a,b,ctx);
		BN_sub(d,d,e);
		BN_div(a,b,d,c,ctx);
		if(!BN_is_zero(b))
		    {
		    fprintf(stderr,"Modulo multiply test failed!\n");
		    ERR_print_errors_fp(stderr);
		    return 0;
		    }
		}
	}
	BN_free(a);
	BN_free(b);
	BN_free(c);
	BN_free(d);
	BN_free(e);
	return(1);
	}
示例#26
0
文件: tunala.c 项目: 119120119/node
static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id,
                                   const char *CAfile, const char *cert,
                                   const char *key, const char *dcert,
                                   const char *dkey, const char *cipher_list,
                                   const char *dh_file,
                                   const char *dh_special, int tmp_rsa,
                                   int ctx_options, int out_state,
                                   int out_verify, int verify_mode,
                                   unsigned int verify_depth)
{
    SSL_CTX *ctx = NULL, *ret = NULL;
    const SSL_METHOD *meth;
    ENGINE *e = NULL;

    OpenSSL_add_ssl_algorithms();
    SSL_load_error_strings();

    meth = (server_mode ? SSLv23_server_method() : SSLv23_client_method());
    if (meth == NULL)
        goto err;
    if (engine_id) {
        ENGINE_load_builtin_engines();
        if ((e = ENGINE_by_id(engine_id)) == NULL) {
            fprintf(stderr, "Error obtaining '%s' engine, openssl "
                    "errors follow\n", engine_id);
            goto err;
        }
        if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
            fprintf(stderr, "Error assigning '%s' engine, openssl "
                    "errors follow\n", engine_id);
            goto err;
        }
        ENGINE_free(e);
    }
    if ((ctx = SSL_CTX_new(meth)) == NULL)
        goto err;
    /* cacert */
    if (CAfile) {
        if (!X509_STORE_load_locations(SSL_CTX_get_cert_store(ctx),
                                       CAfile, NULL)) {
            fprintf(stderr, "Error loading CA cert(s) in '%s'\n", CAfile);
            goto err;
        }
        fprintf(stderr, "Info, operating with CA cert(s) in '%s'\n", CAfile);
    } else
        fprintf(stderr, "Info, operating without a CA cert(-list)\n");
    if (!SSL_CTX_set_default_verify_paths(ctx)) {
        fprintf(stderr, "Error setting default verify paths\n");
        goto err;
    }

    /* cert and key */
    if ((cert || key) && !ctx_set_cert(ctx, cert, key))
        goto err;
    /* dcert and dkey */
    if ((dcert || dkey) && !ctx_set_cert(ctx, dcert, dkey))
        goto err;
    /* temporary RSA key generation */
    if (tmp_rsa)
        SSL_CTX_set_tmp_rsa_callback(ctx, cb_generate_tmp_rsa);

    /* cipher_list */
    if (cipher_list) {
        if (!SSL_CTX_set_cipher_list(ctx, cipher_list)) {
            fprintf(stderr, "Error setting cipher list '%s'\n", cipher_list);
            goto err;
        }
        fprintf(stderr, "Info, set cipher list '%s'\n", cipher_list);
    } else
        fprintf(stderr, "Info, operating with default cipher list\n");

    /* dh_file & dh_special */
    if ((dh_file || dh_special) && !ctx_set_dh(ctx, dh_file, dh_special))
        goto err;

    /* ctx_options */
    SSL_CTX_set_options(ctx, ctx_options);

    /* out_state (output of SSL handshake states to screen). */
    if (out_state)
        cb_ssl_info_set_output(stderr);

    /* out_verify */
    if (out_verify > 0) {
        cb_ssl_verify_set_output(stderr);
        cb_ssl_verify_set_level(out_verify);
    }

    /* verify_depth */
    cb_ssl_verify_set_depth(verify_depth);

    /* Success! (includes setting verify_mode) */
    SSL_CTX_set_info_callback(ctx, cb_ssl_info);
    SSL_CTX_set_verify(ctx, verify_mode, cb_ssl_verify);
    ret = ctx;
 err:
    if (!ret) {
        ERR_print_errors_fp(stderr);
        if (ctx)
            SSL_CTX_free(ctx);
    }
    return ret;
}
示例#27
0
int SFSocketConnectToHost (SFSocket *clientSocket, const char *host, int port) {
    struct sockaddr_in *addr = NULL;
    struct hostent *hp = NULL;
    SSL_CTX *ctx = NULL;
    int sock = 0;

    if ((hp = gethostbyname(host)) == NULL)
        return(-1);

    /* Setup Address */
    addr = SFSocketAddress(clientSocket);
    memset(addr, 0, sizeof(struct sockaddr_in));
    addr->sin_addr = *((struct in_addr *)hp->h_addr_list[0]);
    addr->sin_family = AF_INET;
    addr->sin_port = htons(port);

#ifdef _WIN32
    if ( INVALID_SOCKET == (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) )
#else
	if (0 > (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
#endif
		return(-2);

    /* Connect to Host */
#ifdef _WIN32
	if (SOCKET_ERROR == connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) )
#else
	if (0 > connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in)))
#endif
	{
#ifdef _WIN32
		errno_t theError = WSAGetLastError();
        closesocket(sock);
#else
		close(sock);
#endif
		sock = 0;
		return(-3);
    }

    /* Set Socket Descriptor */
    SFSocketSetDescriptor(clientSocket, sock);
    
    if (NULL != (ctx = SFSocketContext(clientSocket))) {
        BIO *bio = NULL;
        SSL *ssl = NULL;

        /* Setup SSL */
        if (NULL == (ssl = SSL_new(ctx))) {
            ERR_print_errors_fp(stderr);
            SFSocketClearDescriptor(clientSocket);
#ifdef _WIN32
            closesocket(sock);
#else
			close(sock);
#endif
			sock = 0;
            return(-4);
        }

        /* Setup BIO */
        if ((bio = BIO_new_socket(sock, BIO_NOCLOSE)) == NULL) {
            SFSocketClearDescriptor(clientSocket);
            SSL_free(ssl);
#ifdef _WIN32
            closesocket(sock);
#else
			close(sock);
#endif
			sock = 0;
			return(-5);
        }

        /* SSL Connect */
        SSL_set_bio(ssl, bio, bio);
        if (0 >= SSL_connect(ssl)) {
            ERR_print_errors_fp(stderr);
            return(-6);
        }

        /* Setup SSL/BIO on Socket */
        SFSocketSetSSL(clientSocket, ssl);
        SFSocketSetBIO(clientSocket, bio);

		//TODO Figure out why Certs weren't working.
		// TODO get certs working.
		// TODO otherwise at least figure out how to call this without a cert
        /* Check Certificate */
//        if (__SFSocketCheckCert(clientSocket, host) < 0)
//            return(-7);
    }

    return(0);
}
示例#28
0
/* handles a client connection */
void handle_connection(int sock){
        u_int32_t calculated_crc32;
	command *temp_command;
	packet receive_packet;
	packet send_packet;
	int bytes_to_send;
	int bytes_to_recv;
	char buffer[MAX_INPUT_BUFFER];
	char raw_command[MAX_INPUT_BUFFER];
	char processed_command[MAX_INPUT_BUFFER];
	int result=STATE_OK;
	int early_timeout=FALSE;
	int rc;
	int x;
#ifdef DEBUG
	FILE *errfp;
#endif
#ifdef HAVE_SSL
	SSL *ssl=NULL;
#endif


	/* log info to syslog facility */
	if(debug==TRUE)
		syslog(LOG_DEBUG,"Handling the connection...");

#ifdef OLDSTUFF
	/* socket should be non-blocking */
	fcntl(sock,F_SETFL,O_NONBLOCK);
#endif

	/* set connection handler */
	signal(SIGALRM,my_connection_sighandler);
	alarm(connection_timeout);

#ifdef HAVE_SSL
	/* do SSL handshake */
	if(result==STATE_OK && use_ssl==TRUE){
		if((ssl=SSL_new(ctx))!=NULL){
			SSL_set_fd(ssl,sock);

			/* keep attempting the request if needed */
                        while(((rc=SSL_accept(ssl))!=1) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ));

			if(rc!=1){
				syslog(LOG_ERR,"Error: Could not complete SSL handshake. %d\n",SSL_get_error(ssl,rc));
#ifdef DEBUG
				errfp=fopen("/tmp/err.log","w");
				ERR_print_errors_fp(errfp);
				fclose(errfp);
#endif
				return;
			        }
		        }
		else{
			syslog(LOG_ERR,"Error: Could not create SSL connection structure.\n");
#ifdef DEBUG
			errfp=fopen("/tmp/err.log","w");
			ERR_print_errors_fp(errfp);
			fclose(errfp);
#endif
			return;
		        }
	        }
#endif

	bytes_to_recv=sizeof(receive_packet);
	if(use_ssl==FALSE)
		rc=recvall(sock,(char *)&receive_packet,&bytes_to_recv,socket_timeout);
#ifdef HAVE_SSL
	else{
                while(((rc=SSL_read(ssl,&receive_packet,bytes_to_recv))<=0) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ));
		}
#endif

	/* recv() error or client disconnect */
	if(rc<=0){

		/* log error to syslog facility */
		syslog(LOG_ERR,"Could not read request from client, bailing out...");

#ifdef HAVE_SSL
		if(ssl){
			SSL_shutdown(ssl);
			SSL_free(ssl);
			syslog(LOG_INFO,"INFO: SSL Socket Shutdown.\n");
			}
#endif

		return;
                }

	/* we couldn't read the correct amount of data, so bail out */
	else if(bytes_to_recv!=sizeof(receive_packet)){

		/* log error to syslog facility */
		syslog(LOG_ERR,"Data packet from client was too short, bailing out...");

#ifdef HAVE_SSL
		if(ssl){
			SSL_shutdown(ssl);
			SSL_free(ssl);
			}
#endif

		return;
	        }

#ifdef DEBUG
	fp=fopen("/tmp/packet","w");
	if(fp){
		fwrite(&receive_packet,1,sizeof(receive_packet),fp);
		fclose(fp);
	        }
#endif

	/* make sure the request is valid */
	if(validate_request(&receive_packet)==ERROR){

		/* log an error */
		syslog(LOG_ERR,"Client request was invalid, bailing out...");

		/* free memory */
		free(command_name);
		command_name=NULL;
		for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){
			free(macro_argv[x]);
			macro_argv[x]=NULL;
	                }

#ifdef HAVE_SSL
		if(ssl){
			SSL_shutdown(ssl);
			SSL_free(ssl);
			}
#endif

		return;
	        }

	/* log info to syslog facility */
	if(debug==TRUE)
		syslog(LOG_DEBUG,"Host is asking for command '%s' to be run...",receive_packet.buffer);

	/* disable connection alarm - a new alarm will be setup during my_system */
	alarm(0);

	/* if this is the version check command, just spew it out */
	if(!strcmp(command_name,NRPE_HELLO_COMMAND)){

		snprintf(buffer,sizeof(buffer),"NRPE v%s",PROGRAM_VERSION);
		buffer[sizeof(buffer)-1]='\x0';

		/* log info to syslog facility */
		if(debug==TRUE)
			syslog(LOG_DEBUG,"Response: %s",buffer);

		result=STATE_OK;
	        }

	/* find the command we're supposed to run */
	else{
		temp_command=find_command(command_name);
		if(temp_command==NULL){

			snprintf(buffer,sizeof(buffer),"NRPE: Command '%s' not defined",command_name);
			buffer[sizeof(buffer)-1]='\x0';

			/* log error to syslog facility */
			if(debug==TRUE)
				syslog(LOG_DEBUG,"%s",buffer);

			result=STATE_CRITICAL;
	                }

		else{

			/* process command line */
			if(command_prefix==NULL)
				strncpy(raw_command,temp_command->command_line,sizeof(raw_command)-1);
			else
				snprintf(raw_command,sizeof(raw_command)-1,"%s %s",command_prefix,temp_command->command_line);
			raw_command[sizeof(raw_command)-1]='\x0';
			process_macros(raw_command,processed_command,sizeof(processed_command));

			/* log info to syslog facility */
			if(debug==TRUE)
				syslog(LOG_DEBUG,"Running command: %s",processed_command);

			/* run the command */
			strcpy(buffer,"");
			result=my_system(processed_command,command_timeout,&early_timeout,buffer,sizeof(buffer));

			/* log debug info */
			if(debug==TRUE)
				syslog(LOG_DEBUG,"Command completed with return code %d and output: %s",result,buffer);

			/* see if the command timed out */
			if(early_timeout==TRUE)
				snprintf(buffer,sizeof(buffer)-1,"NRPE: Command timed out after %d seconds\n",command_timeout);
			else if(!strcmp(buffer,""))
				snprintf(buffer,sizeof(buffer)-1,"NRPE: Unable to read output\n");

			buffer[sizeof(buffer)-1]='\x0';

			/* check return code bounds */
			if((result<0) || (result>3)){

				/* log error to syslog facility */
				syslog(LOG_ERR,"Bad return code for [%s]: %d", buffer,result);

				result=STATE_UNKNOWN;
			        }
		        }
	        }

	/* free memory */
	free(command_name);
	command_name=NULL;
	for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){
		free(macro_argv[x]);
		macro_argv[x]=NULL;
	        }

	/* strip newline character from end of output buffer */
	if(buffer[strlen(buffer)-1]=='\n')
		buffer[strlen(buffer)-1]='\x0';

	/* clear the response packet buffer */
	bzero(&send_packet,sizeof(send_packet));

	/* fill the packet with semi-random data */
	randomize_buffer((char *)&send_packet,sizeof(send_packet));

	/* initialize response packet data */
	send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2);
	send_packet.packet_type=(int16_t)htons(RESPONSE_PACKET);
	send_packet.result_code=(int16_t)htons(result);
	strncpy(&send_packet.buffer[0],buffer,MAX_PACKETBUFFER_LENGTH);
	send_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0';
	
	/* calculate the crc 32 value of the packet */
	send_packet.crc32_value=(u_int32_t)0L;
	calculated_crc32=calculate_crc32((char *)&send_packet,sizeof(send_packet));
	send_packet.crc32_value=(u_int32_t)htonl(calculated_crc32);


	/***** ENCRYPT RESPONSE *****/


	/* send the response back to the client */
	bytes_to_send=sizeof(send_packet);
	if(use_ssl==FALSE)
		sendall(sock,(char *)&send_packet,&bytes_to_send);
#ifdef HAVE_SSL
	else
		SSL_write(ssl,&send_packet,bytes_to_send);
#endif

#ifdef HAVE_SSL
	if(ssl){
		SSL_shutdown(ssl);
		SSL_free(ssl);
		}
#endif

	/* log info to syslog facility */
	if(debug==TRUE)
		syslog(LOG_DEBUG,"Return Code: %d, Output: %s",result,buffer);

	return;
        }
示例#29
0
文件: dhtest.c 项目: 1234-/openssl
int main(int argc, char *argv[])
{
    BN_GENCB *_cb = NULL;
    DH *a = NULL;
    DH *b = NULL;
    BIGNUM *ap = NULL, *ag = NULL, *bp = NULL, *bg = NULL, *apub_key = NULL;
    BIGNUM *bpub_key = NULL, *priv_key = NULL;
    char buf[12] = {0};
    unsigned char *abuf = NULL;
    unsigned char *bbuf = NULL;
    int i, alen, blen, aout, bout;
    int ret = 1;
    BIO *out = NULL;

    CRYPTO_set_mem_debug(1);
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

    RAND_seed(rnd_seed, sizeof rnd_seed);

    out = BIO_new(BIO_s_file());
    if (out == NULL)
        EXIT(1);
    BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);

    _cb = BN_GENCB_new();
    if (_cb == NULL)
        goto err;
    BN_GENCB_set(_cb, &cb, out);
    if (((a = DH_new()) == NULL)
        || (!DH_generate_parameters_ex(a, 64, DH_GENERATOR_5, _cb)))
        goto err;

    if (!DH_check(a, &i))
        goto err;
    if (i & DH_CHECK_P_NOT_PRIME)
        BIO_puts(out, "p value is not prime\n");
    if (i & DH_CHECK_P_NOT_SAFE_PRIME)
        BIO_puts(out, "p value is not a safe prime\n");
    if (i & DH_UNABLE_TO_CHECK_GENERATOR)
        BIO_puts(out, "unable to check the generator value\n");
    if (i & DH_NOT_SUITABLE_GENERATOR)
        BIO_puts(out, "the g value is not a generator\n");

    DH_get0_pqg(a, &ap, NULL, &ag);
    BIO_puts(out, "\np    =");
    BN_print(out, ap);
    BIO_puts(out, "\ng    =");
    BN_print(out, ag);
    BIO_puts(out, "\n");

    b = DH_new();
    if (b == NULL)
        goto err;

    bp = BN_dup(ap);
    bg = BN_dup(ag);
    if ((bp == NULL) || (bg == NULL) || !DH_set0_pqg(b, bp, NULL, bg))
        goto err;
    bp = bg = NULL;

    if (!DH_generate_key(a))
        goto err;
    DH_get0_key(a, &apub_key, &priv_key);
    BIO_puts(out, "pri 1=");
    BN_print(out, priv_key);
    BIO_puts(out, "\npub 1=");
    BN_print(out, apub_key);
    BIO_puts(out, "\n");

    if (!DH_generate_key(b))
        goto err;
    DH_get0_key(b, &bpub_key, &priv_key);
    BIO_puts(out, "pri 2=");
    BN_print(out, priv_key);
    BIO_puts(out, "\npub 2=");
    BN_print(out, bpub_key);
    BIO_puts(out, "\n");

    alen = DH_size(a);
    abuf = OPENSSL_malloc(alen);
    if (abuf == NULL)
        goto err;

    aout = DH_compute_key(abuf, bpub_key, a);

    BIO_puts(out, "key1 =");
    for (i = 0; i < aout; i++) {
        sprintf(buf, "%02X", abuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");

    blen = DH_size(b);
    bbuf = OPENSSL_malloc(blen);
    if (bbuf == NULL)
        goto err;

    bout = DH_compute_key(bbuf, apub_key, b);

    BIO_puts(out, "key2 =");
    for (i = 0; i < bout; i++) {
        sprintf(buf, "%02X", bbuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");
    if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) {
        fprintf(stderr, "Error in DH routines\n");
        ret = 1;
    } else
        ret = 0;
    if (!run_rfc5114_tests())
        ret = 1;
 err:
    (void)BIO_flush(out);
    ERR_print_errors_fp(stderr);

    OPENSSL_free(abuf);
    OPENSSL_free(bbuf);
    DH_free(b);
    DH_free(a);
    BN_free(bp);
    BN_free(bg);
    BN_GENCB_free(_cb);
    BIO_free(out);

#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    if (CRYPTO_mem_leaks_fp(stderr) <= 0)
        ret = 1;
#endif

    EXIT(ret);
}
示例#30
0
int main(int argc, char **argv)
{
	int debug=0;
	int verify=0;
	int mismatch=0;
	char *program;
	int badops=0;
	char *certfile=NULL;
	char *out1file=NULL;
	char *out2file=NULL;
	char *home=NULL;
	char *pin=NULL;
	char *argp;
	char *ss;
	BIO *bio_err;
	X509 *ucert;

	FILE *fp;
	FILE *fpout;

#ifdef USE_PKCS11
    CK_SESSION_HANDLE hSession = 0;
#endif


#ifdef WIN32
	CRYPTO_malloc_init();
#endif

	ERR_load_prxyerr_strings(0);
	SSLeay_add_ssl_algorithms();

	if ((bio_err=BIO_new(BIO_s_file())) != NULL) {
        BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
	}

	program=argv[0];
	argc--;
	argv++;
	while (argc >= 1) {
		argp = *argv;
		if ( *argp == '-' && *(argp+1) == '-') {
			argp++;
		}
		if  (strcmp(argp,"-debug") == 0) {
			debug++;
		}
		else if (strcmp(argp,"-cert") == 0) {
			if (--argc < 1) goto bad;
			certfile=*(++argv);
		} 
		else if (strcmp(argp,"-out1") == 0) {
			if (--argc < 1) goto bad;
			out1file=*(++argv);
		} 
		else if (strcmp(argp,"-out2") == 0) {
			if (--argc < 1) goto bad;
			out2file=*(++argv);
		} 
		else if (strcmp(argp,"-help") == 0) {
			badops=1;
			break;
		}
		else {
			fprintf(stderr,_GGSL("unknown option %s\n"),*argv);
			badops=1;
			break;
		}
		argc--;
		argv++;
	}

	if (badops) {
bad:
		fprintf(stderr,_GGSL("%s [options]\n"),program);
		fprintf(stderr,_GGSL("where options  are\n"));
		fprintf(stderr,_GGSL(" --help    show this list\n"));
		fprintf(stderr,_GGSL(" --debug   set debugging on\n"));
		fprintf(stderr,_GGSL(" --cert    file name of long term certificate\n"));
		fprintf(stderr,_GGSL(" --out1     file name for name\n"));
		fprintf(stderr,_GGSL(" --out2    file name for commonName\n");
		exit(1);
	}
	home = (char *)getenv("HOME");
	if (home == NULL) {
#ifndef WIN32
		fprintf(stderr,_GGSL("$HOME not defined"));
		exit(1);
#else
		home = "c:\\windows";
#endif
	}

	if (!strncmp(certfile,"SC:",3)) {
#ifdef USE_PKCS11
        char *cp;
        char *kp;
        int rc;
        cp = certfile + 3;
        kp = strchr(cp,':');
        if (kp == NULL) {
            fprintf(stderr,_GGSL("Bad format of cert name, SC:card:cert\n"));
            exit (2);
        }
        kp++; /* skip the : */
        if (hSession == 0) {
            rc = sc_init(&hSession, cp, NULL, pin, CKU_USER, 0);
            if (rc) {
                fprintf(stderr,_GGSL("Failed to open card session\n"));
                ERR_print_errors_fp (stderr);
                exit(2);
            }
        }


        rc = sc_get_cert_obj_by_label(hSession,kp,&ucert);
        if (rc) {
            fprintf(stderr,_GGSL("Failed to find certificate on card \n"));
            ERR_print_errors_fp (stderr);
            exit(2);
        }
#else
        fprintf(stderr,_GGSL("Smart card support not compiled with this program\n"));
            exit (2);
#endif /* USE_PKCS11 */

	} else {
		fp = fopen (certfile, "r");
		if (fp == NULL) {
			fprintf(stderr,_GGSL(" failed to open %s\n",certfile));
	 		exit (1);
		}

		ucert = PEM_read_X509 (fp, NULL, OPENSSL_PEM_CB(NULL, NULL));
		fclose (fp);
}

	if (ucert == NULL) {
		ERR_print_errors_fp (stderr);
		exit (1); 
	}

	if (out1file) {
		if (strcmp("-",out1file)) {
			fpout=fopen(out1file,"w");
		} else {
			fpout = stdout;
		}
		if (fpout == NULL) {
			fprintf (stderr,"Unable to open out1 file:%s\n", out1file);
			exit(4);
		}
		ss = X509_NAME_oneline(ucert->cert_info->subject,NULL,0);
		while (1) {
			if (!strcmp(ss+strlen(ss)-strlen("/CN=limited proxy"),
								"/CN=limited proxy")) {
				*(ss+strlen(ss)-strlen("/CN=limited proxy"))= '\0';
			} else
			if (!strcmp(ss+strlen(ss)-strlen("/CN=proxy"),
					"/CN=proxy")) {
				*(ss+strlen(ss)-strlen("/CN=proxy")) = '\0';
			} else {
				break;
			}
		}
		
		fprintf(fpout,"%s\n",ss);
		OPENSSL_free(ss);

		if (fpout != stdout) {
			fclose(fpout);
		}
	}


	if (out2file) {
		if (strcmp("-",out2file)) {
			fpout=fopen(out2file,"w");
		} else {
			fpout = stdout;
		}
		if (fpout == NULL) {
			fprintf (stderr,"Unable to open out2 file:%s\n", out2file);
			exit(4);
		}
		{
			X509_NAME *subject;
			X509_NAME_ENTRY *ne;
			ASN1_STRING *data;
			X509_NAME_ENTRY *o = NULL;
			X509_NAME_ENTRY *ou1 = NULL;
			X509_NAME_ENTRY *ou2 = NULL;
			int i;
	
			subject=X509_get_subject_name(ucert);
			i = X509_NAME_entry_count(subject)-1;
			while (i > 0) {
				ne=X509_NAME_get_entry(subject,i);
				if (!OBJ_cmp(ne->object,
						OBJ_nid2obj(NID_organizationName))) {
					if (!o) {
						o = ne;
					}
				}
				if (!OBJ_cmp(ne->object,
						OBJ_nid2obj(NID_organizationalUnitName))) {
					if (ou2) { 
						ou1 = ne;
					} else { 
						ou2 = ne;
					}
				}
				if (!OBJ_cmp(ne->object,
						OBJ_nid2obj(NID_commonName))) {
					data=X509_NAME_ENTRY_get_data(ne);
					if ((data->length == 5 &&
							!memcmp(data->data,"proxy",5)) ||
						(data->length == 13 &&
							!memcmp(data->data,"limited proxy",13))) {
							i--;
							continue;
					}
					fprintf(fpout,"%.*s\n",data->length,data->data);
					/* break; */
				}	
				i--;
			} 
			if (o) {
				data=X509_NAME_ENTRY_get_data(o);
				fprintf(fpout,"%.*s\n",data->length,data->data);
			}
			if (ou1) {
				data=X509_NAME_ENTRY_get_data(ou1);
				fprintf(fpout,"%.*s\n",data->length,data->data);
			}
			if (ou2) {
				data=X509_NAME_ENTRY_get_data(ou2);
				fprintf(fpout,"%.*s\n",data->length,data->data);
			}
		} /* inline section */
			

		if (fpout != stdout) {
			fclose(fpout);
		}
	} /* out2file */

	return 0;

}