Пример #1
0
int main(void) {
	EVP_CIPHER_CTX *ctx = NULL;
	unsigned char key[16];
	unsigned char iv[12];
	unsigned char tag[16];
	unsigned char data[128];
	unsigned char ori_msg[128];
	unsigned char enc_msg[128+16];
	unsigned char dec_msg[128];
	int r, len, enc_msg_len, dec_msg_len;
	const EVP_CIPHER* cipher = NULL;

	ERR_load_CRYPTO_strings();
	OPENSSL_add_all_algorithms_noconf();

	r = RAND_bytes(key, sizeof(key));
	assert(r == 1);
	r = RAND_bytes(iv, sizeof(iv));
	assert(r == 1);
	r = RAND_pseudo_bytes(data, sizeof(data));
	assert(r == 1);
	r = RAND_pseudo_bytes(ori_msg, sizeof(ori_msg));
	assert(r == 1);
	r = RAND_pseudo_bytes(enc_msg, sizeof(enc_msg));
	assert(r == 1);

	cipher = EVP_aes_128_gcm();

	ctx = EVP_CIPHER_CTX_new();
	assert(ctx);

	EVP_CIPHER_CTX_init(ctx);

	len = EVP_CIPHER_key_length(cipher);
	assert(len == sizeof(key));

	len = EVP_CIPHER_iv_length(cipher);
	assert(len == sizeof(iv));


	r = EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv);
	assert(r == 1);

	r = EVP_EncryptUpdate(ctx, NULL, &enc_msg_len, data, sizeof(data));
	assert(r == 1);

	r = EVP_EncryptUpdate(ctx, enc_msg, &enc_msg_len, ori_msg, sizeof(ori_msg));
	assert(r == 1);
	assert(enc_msg_len == sizeof(ori_msg));

	r = EVP_EncryptFinal_ex(ctx, enc_msg + enc_msg_len, &len);
	assert(r == 1);
	assert(len == 0);

	r = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, sizeof(tag), tag);
	assert(r == 1);


	r = EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv);
	assert(r == 1);

	r = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof(tag), tag);
	assert(r == 1);

	r = EVP_DecryptUpdate(ctx, NULL, &dec_msg_len, data, sizeof(data));
	assert(r == 1);

	r = EVP_DecryptUpdate(ctx, dec_msg, &dec_msg_len, enc_msg, enc_msg_len);
	assert(r == 1);
	assert(dec_msg_len == enc_msg_len);

	r = EVP_DecryptFinal_ex(ctx, dec_msg + dec_msg_len, &len);
	assert(r == 1);
	assert(len == 0);

	assert(memcmp(ori_msg, dec_msg, dec_msg_len) == 0);


	EVP_CIPHER_CTX_free(ctx);

	puts("OK!");
	return 0;
}
Пример #2
0
int main(int argc, char *argv[])
{
    BN_CTX *ctx;
    BIO *out = NULL;
    int i, ret;
    unsigned char c;
    BIGNUM *r_mont, *r_mont_const, *r_recp, *r_simple, *a, *b, *m;

    RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we
                                           * don't even check its return
                                           * value (which we should) */

    ERR_load_BN_strings();

    ctx = BN_CTX_new();
    if (ctx == NULL)
        EXIT(1);
    r_mont = BN_new();
    r_mont_const = BN_new();
    r_recp = BN_new();
    r_simple = BN_new();
    a = BN_new();
    b = BN_new();
    m = BN_new();
    if ((r_mont == NULL) || (r_recp == NULL) || (a == NULL) || (b == NULL))
        goto err;

    out = BIO_new(BIO_s_file());

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

    for (i = 0; i < 200; i++) {
        RAND_bytes(&c, 1);
        c = (c % BN_BITS) - BN_BITS2;
        BN_rand(a, NUM_BITS + c, 0, 0);

        RAND_bytes(&c, 1);
        c = (c % BN_BITS) - BN_BITS2;
        BN_rand(b, NUM_BITS + c, 0, 0);

        RAND_bytes(&c, 1);
        c = (c % BN_BITS) - BN_BITS2;
        BN_rand(m, NUM_BITS + c, 0, 1);

        BN_mod(a, a, m, ctx);
        BN_mod(b, b, m, ctx);

        ret = BN_mod_exp_mont(r_mont, a, b, m, ctx, NULL);
        if (ret <= 0) {
            printf("BN_mod_exp_mont() problems\n");
            ERR_print_errors(out);
            EXIT(1);
        }

        ret = BN_mod_exp_recp(r_recp, a, b, m, ctx);
        if (ret <= 0) {
            printf("BN_mod_exp_recp() problems\n");
            ERR_print_errors(out);
            EXIT(1);
        }

        ret = BN_mod_exp_simple(r_simple, a, b, m, ctx);
        if (ret <= 0) {
            printf("BN_mod_exp_simple() problems\n");
            ERR_print_errors(out);
            EXIT(1);
        }

        ret = BN_mod_exp_mont_consttime(r_mont_const, a, b, m, ctx, NULL);
        if (ret <= 0) {
            printf("BN_mod_exp_mont_consttime() problems\n");
            ERR_print_errors(out);
            EXIT(1);
        }

        if (BN_cmp(r_simple, r_mont) == 0
            && BN_cmp(r_simple, r_recp) == 0
            && BN_cmp(r_simple, r_mont_const) == 0) {
            printf(".");
            fflush(stdout);
        } else {
            if (BN_cmp(r_simple, r_mont) != 0)
                printf("\nsimple and mont results differ\n");
            if (BN_cmp(r_simple, r_mont_const) != 0)
                printf("\nsimple and mont const time results differ\n");
            if (BN_cmp(r_simple, r_recp) != 0)
                printf("\nsimple and recp results differ\n");

            printf("a (%3d) = ", BN_num_bits(a));
            BN_print(out, a);
            printf("\nb (%3d) = ", BN_num_bits(b));
            BN_print(out, b);
            printf("\nm (%3d) = ", BN_num_bits(m));
            BN_print(out, m);
            printf("\nsimple   =");
            BN_print(out, r_simple);
            printf("\nrecp     =");
            BN_print(out, r_recp);
            printf("\nmont     =");
            BN_print(out, r_mont);
            printf("\nmont_ct  =");
            BN_print(out, r_mont_const);
            printf("\n");
            EXIT(1);
        }
    }
    BN_free(r_mont);
    BN_free(r_mont_const);
    BN_free(r_recp);
    BN_free(r_simple);
    BN_free(a);
    BN_free(b);
    BN_free(m);
    BN_CTX_free(ctx);
    ERR_remove_thread_state(NULL);
    CRYPTO_mem_leaks(out);
    BIO_free(out);
    printf("\n");

    if (test_exp_mod_zero() != 0)
        goto err;

    printf("done\n");

    EXIT(0);
 err:
    ERR_load_crypto_strings();
    ERR_print_errors(out);
#ifdef OPENSSL_SYS_NETWARE
    printf("ERROR\n");
#endif
    EXIT(1);
    return (1);
}
Пример #3
0
SESSION *session_init_client (void)
{
	SESSION *session;

	if ((session = (SESSION *) calloc (1, sizeof (SESSION))) == NULL)
		return NULL;

	session->client_OS = 0x00;	/* 0x00 == Windows, 0x01 == Mac OS X */
	memcpy(session->client_id, "\x01\x04\x01\x01", 4);
	session->client_revision = 99999;
	
	/*
	 * Client and server generate 16 random bytes each.
	 */
	RAND_bytes (session->client_random_16, 16);

	if ((session->rsa =
	     RSA_generate_key (1024, 65537, NULL, NULL)) == NULL) {
		DSFYDEBUG ("RSA key generation failed with error %lu\n",
			   ERR_get_error ());
	}
	assert (session->rsa != NULL);

	/*
	 * Create a private and public key.
	 * This, along with key signing, is used to securely
	 * agree on a session key for the Shannon stream cipher.
	 *
	 */
	session->dh = DH_new ();
	session->dh->p = BN_bin2bn (DH_prime, 96, NULL);
	session->dh->g = BN_bin2bn (DH_generator, 1, NULL);
	assert (DH_generate_key (session->dh) == 1);

	BN_bn2bin (session->dh->priv_key, session->my_priv_key);
	BN_bn2bin (session->dh->pub_key, session->my_pub_key);

	/*
	 * Found in Storage.dat (cache) at offset 16.
	 * Automatically generated, but we're lazy.
	 *
	 */
	memcpy (session->cache_hash,
		"\xf4\xc2\xaa\x05\xe8\x25\xa7\xb5\xe4\xe6\x59\x0f\x3d\xd0\xbe\x0a\xef\x20\x51\x95",
		20);
	session->cache_hash[0] = (unsigned char) getpid ();

	session->ap_sock = -1;
	session->username[0] = 0;
	session->server_host[0] = 0;
	session->server_port = 0;

	session->key_recv_IV = 0;
	session->key_send_IV = 0;

	session->user_info.username[0] = 0;
	session->user_info.country[0] = 0;
	session->user_info.server_host[0] = 0;
	session->user_info.server_port = 0;

	return session;
}
Пример #4
0
X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
                                  const unsigned char *salt, int saltlen,
                                  unsigned char *aiv, uint64_t N, uint64_t r,
                                  uint64_t p)
{
    X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
    int alg_nid;
    size_t keylen = 0;
    EVP_CIPHER_CTX *ctx = NULL;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    PBE2PARAM *pbe2 = NULL;
    ASN1_OBJECT *obj;

    if (!cipher) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_PASSED_NULL_PARAMETER);
        goto err;
    }

    if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
                ASN1_R_INVALID_SCRYPT_PARAMETERS);
        goto err;
    }

    alg_nid = EVP_CIPHER_type(cipher);
    if (alg_nid == NID_undef) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
        goto err;
    }
    obj = OBJ_nid2obj(alg_nid);
    pbe2 = PBE2PARAM_new();
    if (pbe2 == NULL)
        goto merr;

    /* Setup the AlgorithmIdentifier for the encryption scheme */
    scheme = pbe2->encryption;

    scheme->algorithm = obj;
    scheme->parameter = ASN1_TYPE_new();
    if (scheme->parameter == NULL)
        goto merr;

    /* Create random IV */
    if (EVP_CIPHER_iv_length(cipher)) {
        if (aiv)
            memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
        else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
            goto err;
    }

    ctx = EVP_CIPHER_CTX_new();
    if (ctx == NULL)
        goto merr;

    /* Dummy cipherinit to just setup the IV */
    if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0)
        goto err;
    if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) < 0) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
                ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
        goto err;
    }
    EVP_CIPHER_CTX_free(ctx);
    ctx = NULL;

    /* If its RC2 then we'd better setup the key length */

    if (alg_nid == NID_rc2_cbc)
        keylen = EVP_CIPHER_key_length(cipher);

    /* Setup keyfunc */

    X509_ALGOR_free(pbe2->keyfunc);

    pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p);

    if (pbe2->keyfunc == NULL)
        goto merr;

    /* Now set up top level AlgorithmIdentifier */

    ret = X509_ALGOR_new();
    if (ret == NULL)
        goto merr;

    ret->algorithm = OBJ_nid2obj(NID_pbes2);

    /* Encode PBE2PARAM into parameter */

    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
                                &ret->parameter) == NULL)
        goto merr;

    PBE2PARAM_free(pbe2);
    pbe2 = NULL;

    return ret;

 merr:
    ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_MALLOC_FAILURE);

 err:
    PBE2PARAM_free(pbe2);
    X509_ALGOR_free(kalg);
    X509_ALGOR_free(ret);
    EVP_CIPHER_CTX_free(ctx);

    return NULL;

}
Пример #5
0
static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA1 *key,
	unsigned char *out, const unsigned char *inp, size_t inp_len,
	int n4x)	/* n4x is 1 or 2 */
{
	HASH_DESC	hash_d[8], edges[8];
	CIPH_DESC	ciph_d[8];
	unsigned char	storage[sizeof(SHA1_MB_CTX)+32];
	union {	u64	q[16];
		u32	d[32];
		u8	c[128];	} blocks[8];
	SHA1_MB_CTX	*ctx;
	unsigned int	frag, last, packlen, i, x4=4*n4x;
	size_t		ret = 0;
	u8		*IVs;

	ctx = (SHA1_MB_CTX *)(storage+32-((size_t)storage%32));	/* align */

	frag = (unsigned int)inp_len>>(1+n4x);
	last = (unsigned int)inp_len+frag-(frag<<(1+n4x));
	if (last>frag && ((last+13+9)%64)<(x4-1)) {
		frag++;
		last -= x4-1;
	}

	hash_d[0].ptr = inp;
	for (i=1;i<x4;i++)	hash_d[i].ptr = hash_d[i-1].ptr+frag;

	for (i=0;i<x4;i++) {
		unsigned int len = (i==(x4-1)?last:frag);

		ctx->A[i] = key->md.h0;
		ctx->B[i] = key->md.h1;
		ctx->C[i] = key->md.h2;
		ctx->D[i] = key->md.h3;
		ctx->E[i] = key->md.h4;

		/* fix seqnum */
#if defined(BSWAP8)
		blocks[i].q[0] = BSWAP8(BSWAP8(*(u64*)key->md.data)+i);
#else
		blocks[i].c[7] += ((u8*)key->md.data)[7]+i;
		if (blocks[i].c[7] < i) {
			int j;

			for (j=6;j>=0;j--) {
				if (blocks[i].c[j]=((u8*)key->md.data)[j]+1) break;
			}
		}
#endif
		blocks[i].c[8] = ((u8*)key->md.data)[8];
		blocks[i].c[9] = ((u8*)key->md.data)[9];
		blocks[i].c[10] = ((u8*)key->md.data)[10];
		/* fix length */
		blocks[i].c[11] = (u8)(len>>8);
		blocks[i].c[12] = (u8)(len);

		memcpy(blocks[i].c+13,hash_d[i].ptr,64-13);
		hash_d[i].ptr += 64-13;
		hash_d[i].blocks = (len-(64-13))/64;

		edges[i].ptr = blocks[i].c;
		edges[i].blocks = 1;
	}

	/* hash 13-byte headers and first 64-13 bytes of inputs */
	sha1_multi_block(ctx,edges,n4x);
	/* hash bulk inputs */
	sha1_multi_block(ctx,hash_d,n4x);

	memset(blocks,0,sizeof(blocks));
	for (i=0;i<x4;i++) {
		unsigned int		len = (i==(x4-1)?last:frag),
					off = hash_d[i].blocks*64;
		const unsigned char    *ptr = hash_d[i].ptr+off;

		off = len-(64-13)-off;	/* remainder actually */
		memcpy(blocks[i].c,ptr,off);
		blocks[i].c[off]=0x80;
		len += 64+13;		/* 64 is HMAC header */
		len *= 8;		/* convert to bits */
		if (off<(64-8)) {
			blocks[i].d[15] = BSWAP4(len);
			edges[i].blocks = 1;			
		} else {
			blocks[i].d[31] = BSWAP4(len);
			edges[i].blocks = 2;
		}
		edges[i].ptr = blocks[i].c;
	}

	/* hash input tails and finalize */
	sha1_multi_block(ctx,edges,n4x);

	memset(blocks,0,sizeof(blocks));
	for (i=0;i<x4;i++) {
		blocks[i].d[0] = BSWAP4(ctx->A[i]);	ctx->A[i] = key->tail.h0;
		blocks[i].d[1] = BSWAP4(ctx->B[i]);	ctx->B[i] = key->tail.h1;
		blocks[i].d[2] = BSWAP4(ctx->C[i]);	ctx->C[i] = key->tail.h2;
		blocks[i].d[3] = BSWAP4(ctx->D[i]);	ctx->D[i] = key->tail.h3;
		blocks[i].d[4] = BSWAP4(ctx->E[i]);	ctx->E[i] = key->tail.h4;
		blocks[i].c[20] = 0x80;
		blocks[i].d[15] = BSWAP4((64+20)*8);
		edges[i].ptr = blocks[i].c;
		edges[i].blocks = 1;
	}

	/* finalize MACs */
	sha1_multi_block(ctx,edges,n4x);

	packlen = 5+16+((frag+20+16)&-16);

	out += (packlen<<(1+n4x))-packlen;
	inp += (frag<<(1+n4x))-frag;

	RAND_bytes((IVs=blocks[0].c),16*x4);	/* ask for IVs in bulk */

	for (i=x4-1;;i--) {
		unsigned int len = (i==(x4-1)?last:frag), pad, j;
		unsigned char *out0 = out;

		out += 5+16;		/* place for header and explicit IV */
		ciph_d[i].inp = out;
		ciph_d[i].out = out;

		memmove(out,inp,len);
		out += len;

		/* write MAC */
		((u32 *)out)[0] = BSWAP4(ctx->A[i]);
		((u32 *)out)[1] = BSWAP4(ctx->B[i]);
		((u32 *)out)[2] = BSWAP4(ctx->C[i]);
		((u32 *)out)[3] = BSWAP4(ctx->D[i]);
		((u32 *)out)[4] = BSWAP4(ctx->E[i]);
		out += 20;
		len += 20;

		/* pad */
		pad = 15-len%16;
		for (j=0;j<=pad;j++) *(out++) = pad;
		len += pad+1;

		ciph_d[i].blocks = len/16;
		len += 16;	/* account for explicit iv */

		/* arrange header */
		out0[0] = ((u8*)key->md.data)[8];
		out0[1] = ((u8*)key->md.data)[9];
		out0[2] = ((u8*)key->md.data)[10];
		out0[3] = (u8)(len>>8);
		out0[4] = (u8)(len);

		/* explicit iv */
		memcpy(ciph_d[i].iv, IVs, 16);
		memcpy(&out0[5],     IVs, 16);

		ret += len+5;

		if (i==0) break;

		out = out0-packlen;
		inp -= frag;
		IVs += 16;
	}

	aesni_multi_cbc_encrypt(ciph_d,&key->ks,n4x);

	OPENSSL_cleanse(blocks,sizeof(blocks));
	OPENSSL_cleanse(ctx,sizeof(*ctx));

	return ret;
}
Пример #6
0
int	main(int argc, char *argv[]) {
	int		c, poll = 0, reqversion = 0, rc = -1;
	char		*cacertfile = NULL, *keyfile = NULL, *challenge = NULL,
			*savedrequestfile = NULL, *requestfile = NULL,
			*dn = NULL, *spkacfile = NULL, *endrequest = NULL;
	scep_t		scep;
	BIO		*repbio;
	char		*url = "http://localhost/cgi-bin";
	scepmsg_t	*msg;
	unsigned char	*checkNonce = NULL;

	/* initialize what you can					*/
	scepinit();
	scep_clear(&scep);

	/* we are a client 						*/
	scep.client = 1;

	/* parse command line						*/
	while (EOF != (c = getopt(argc, argv, "dc:e:r:s:k:w:pu:2a:q:")))
		switch (c) {
		case 'd':
			debug++;
			break;
		case 'e':
			endrequest = optarg;
			break;
		case 'c':
			cacertfile = optarg;
			break;
		case 's':
			savedrequestfile = optarg;
		case 'r':
			/* the request file will also contain the self	*/
			/* signed certificate				*/
			requestfile = optarg;
			break;
		case 'k':
			keyfile = optarg;
			break;
		case 'w':
			challenge = optarg;
			break;
		case 'p':
			poll = 1;
			break;
		case 'q':
			scep.community = optarg;
			break;
		case 'u':
			url = optarg;
			break;
		case '2':
			reqversion = 1;
			break;
		case 'a':
			spkacfile = optarg;
			break;
		}

	/* stop immediately if request or key is missing		*/
	/* (even in the case of a version 2 proxied request, we need	*/
	/* a request as the carrier of the proxy entities public key)	*/
	if (keyfile == NULL) {
		BIO_printf(bio_err, "%s:%d: key file is required argument\n",
			__FILE__, __LINE__);
		goto err;
	}
	if (requestfile == NULL) {
		BIO_printf(bio_err, "%s:%d: request file is required "
			"argument\n", __FILE__, __LINE__);
		goto err;
	}

	/* we are preparing the request message				*/
	msg = &scep.request;

	/* decode the URL						*/
	if (parseurl(&scep, url) < 0) {
		BIO_printf(bio_err, "%s:%d: cannot parse url\n", __FILE__,
			__LINE__);
		goto err;
	}
	if (debug)
		BIO_printf(bio_err, "%s:%d: decoded URL %s|%d|%s\n", __FILE__,
			__LINE__, scep.h.httphost, scep.h.httpport,
			scep.h.httppath);

	/* read the client key and request information			*/
	if (read_clientstuff(&scep, requestfile, keyfile) < 0) {
		BIO_printf(bio_err, "%s:%d: failed to read client stuff\n",
			__FILE__, __LINE__);
		goto err;
	}

	/* now we have to decide about the payload we want to have	*/
	/* with our scep request:					*/
	/*  - for a version 1 request, this will always be the original	*/
	/*    certificate signing request				*/
	/*  - for a version 2 request, it will be a payload structure	*/
	switch (reqversion) {
	case 0:
		/* for a version 1 client, client pubkey and client req	*/
		/* coincide						*/
		scep.requestorpubkey = scep.clientpubkey;
		scep.requestorreq = scep.clientreq;
		if (debug)
			BIO_printf(bio_err, "%s:%d: end request coincides "
				"with SCEP client\n", __FILE__, __LINE__);
		break;
	case 1:
		msg->rd.payload = payload_new();
		rc = -1;
		if (spkacfile) {
			if (debug)
				BIO_printf(bio_err, "%s:%d: reading spki "
					"from %s\n", __FILE__, __LINE__,
					spkacfile);
			rc = read_requestorstuff(&scep, 1, spkacfile);
		} else if (endrequest) {
			if (debug)
				BIO_printf(bio_err, "%s:%d: reading X509 req "
					"from %s\n", __FILE__, __LINE__,
					endrequest);
			rc = read_requestorstuff(&scep, 0, endrequest);
		}
		if (rc < 0) {
			BIO_printf(bio_err, "%s:%d: could not read end "
				"request data\n", __FILE__, __LINE__);
			goto err;
		}
		if (debug)
			BIO_printf(bio_err, "%s:%d: end request read\n",
				__FILE__, __LINE__);
		break;
	}

	/* set the transaction id value					*/
	scep.transId = key_fingerprint(scep.requestorpubkey);
	if (debug)
		BIO_printf(bio_err, "%s:%d: transaction ID is %s\n",
			__FILE__, __LINE__, scep.transId);

	/* read the CA certificate file					*/
	if (read_castuff(&scep, cacertfile) < 0) {
		BIO_printf(bio_err, "%s:%d: read CA certificate info\n",
			__FILE__, __LINE__);
	}
	if (debug)
		BIO_printf(bio_err, "%s:%d: CA certificate read\n",
			__FILE__, __LINE__);

	/* for SPKI requests, there should be exactly one more argument	*/
	/* namely the distinguished name				*/
	if (spkacfile) {
		if ((argc - optind) != 1) {
			BIO_printf(bio_err, "%s:%d: DN argument needed\n",
				__FILE__, __LINE__);
			goto err;
		}
		dn = argv[optind];
		if (debug)
			BIO_printf(bio_err, "%s:%d: DN argument is '%s'\n",
				__FILE__, __LINE__, dn);

		/* convert the DN into attributes and add them to the	*/
		/* payload						*/
		if (payload_dn_to_attrs(msg->rd.payload, dn) < 0) {
			BIO_printf(bio_err, "%s:%d: failed to add DN attrs\n",
				__FILE__, __LINE__);
			goto err;
		}
	}

	/* skip creation of a request message when polling		*/
	if (poll)
		goto pollinginit;

	/* pack the request as a PKSCReq message, of type PKCSReq 	*/
	switch (reqversion) {
	case 0:
		msg->messageType = SCEP_MESSAGE_TYPE_PKCSREQ;
		msg->rd.req = scep.clientreq;
		break;
	case 1:
		/* build a version 2 payload				*/
		if (debug)
			BIO_printf(bio_err, "%s:%d: building version 2 "
				"payload\n", __FILE__, __LINE__);
		if (scep.requestorreq)
			payload_set_req(msg->rd.payload, scep.requestorreq);
		if (scep.requestorspki)
			payload_set_spki(msg->rd.payload, scep.requestorspki);

		/* set the correct message type				*/
		if (scep.community) {
			/* compute the authenticator from the original 	*/
			/* request and the community			*/
			msg->messageType = SCEP_MESSAGE_TYPE_V2PROXY;
		} else {
			msg->messageType = SCEP_MESSAGE_TYPE_V2REQUEST;
		}
		break;
	}

	/* write the request to the request file, for later perusal	*/
	if (savedrequestfile) {
		BIO	*reqbio;
		reqbio = BIO_new(BIO_s_file());
		BIO_write_filename(reqbio, savedrequestfile);
		switch (reqversion) {
		case 0:
			/* version 1 request has a X509_REQ payload	*/
			PEM_write_bio_X509_REQ(reqbio, msg->rd.req);
			break;
		case 1:
			/* version 2 requests have a "real" payload	*/
			i2d_payload_bio(reqbio, msg->rd.payload);
			break;
		}
		BIO_free(reqbio);
	}

	goto common;

pollinginit:
	/* when polling, the request is a GetCertInitial message	*/
	msg->messageType = SCEP_MESSAGE_TYPE_GETCERTINITIAL;

	/* the contents is the pair issuer and subject			*/
	msg->rd.is = (issuer_and_subject_t *)malloc(
		sizeof(issuer_and_subject_t));
	msg->rd.is->issuer = X509_get_subject_name(scep.cacert);
	msg->rd.is->subject = NULL;

	/* when polling we should read the request from request file	*/
	/* (only needed for the distinguished name of the client)	*/
	if (debug)
		BIO_printf(bio_err, "%s:%d: getting subject X509_NAME\n",
			__FILE__, __LINE__);
	switch (reqversion) {
	case 0:
		msg->rd.is->subject = X509_REQ_get_subject_name(scep.clientreq);
		break;
	case 1:
		if (scep.requestorreq)
			msg->rd.is->subject
				= X509_REQ_get_subject_name(scep.requestorreq);
		if (scep.requestorspki) {
			if (debug)
				BIO_printf(bio_err, "%s:%d: converting DN '%s' "
					"to X509_NAME\n",
					__FILE__, __LINE__, dn);
			msg->rd.is->subject = ldap_to_x509(dn);
		}
		break;
	}
	if (msg->rd.is->subject == NULL) {
		BIO_printf(bio_err, "%s:%d: no subject found\n", 
			__FILE__, __LINE__);
		goto err;
	}
	if (debug)
		BIO_printf(bio_err, "%s:%d: issuer and subject found\n",
			__FILE__, __LINE__);

common:
	/* create a self signed certificate for use with SCEP		*/
	if (selfsigned(&scep) < 0) {
		BIO_printf(bio_err, "%s:%d: failed to create self signed "
			"certificate\n", __FILE__, __LINE__);
		goto err;
	}
	if (debug)
		BIO_printf(bio_err, "%s:%d: self signed certificate created\n",
			__FILE__, __LINE__);

	/* set the senderNonce						*/
	scep.senderNonceLength = 16;
	scep.senderNonce = (unsigned char *)malloc(scep.senderNonceLength);
	RAND_bytes(scep.senderNonce, scep.senderNonceLength);
	if (debug)
		BIO_printf(bio_err, "%s:%d: senderNonce set\n", __FILE__,
			__LINE__);
	checkNonce = scep.senderNonce;

	/* all messages sent from the client are base 64 encoded	*/
	msg->base64 = 1;

	/* encode							*/
	if (encode(&scep) < 0) {
		BIO_printf(bio_err, "%s:%d: encoding the request failed\n",
			__FILE__, __LINE__);
		goto err;
	}
	if (debug)
		BIO_printf(bio_err, "%s:%d: encoded bytes: %d\n", 
			__FILE__, __LINE__, scep.request.length);

	/* send the request to the server, read the reply		*/
	repbio = getrequest(&scep);
	if (repbio == NULL) {
		BIO_printf(bio_err, "%s:%d: failed to read correct reply\n",
			__FILE__, __LINE__);
		goto err;
	}

	/* analyze  the reply						*/
	if (decode(&scep, repbio) < 0) {
		BIO_printf(bio_err, "%s:%d: decoding the reply failed\n",
			__FILE__, __LINE__);
		goto err;
	}

	/* display some information about the reply			*/
	printf("transaction id: %s\n", scep.transId);
	printf("PKIstatus: %s\n", (scep.reply.pkiStatus)
		? scep.reply.pkiStatus : "(null)");
	printf("reply message type: %s\n", scep.reply.messageType);
	if (scep.reply.failinfo) {
		printf("failinfo: %s\n", scep.reply.failinfo);
	}

	/* make sure we get a CertRep message back			*/
	if (strcmp(scep.reply.messageType, SCEP_MESSAGE_TYPE_CERTREP)) {
		BIO_printf(bio_err, "%s:%d: only CertRep message acceptable "
			" in response to PKCSReq/GetCertInitial\n",
			__FILE__, __LINE__);
		goto err;
	}

	/* check for the Nonces						*/
	if (memcmp(checkNonce, scep.recipientNonce, 16)) {
		BIO_printf(bio_err, "%s:%d: recipientNonce != sent "
			"senderNonce\n", __FILE__, __LINE__);
		goto err;
	}
	if (debug)
		BIO_printf(bio_err, "%s:%d: Nonce check OK\n", __FILE__, 
			__LINE__);

	if (scep.reply.pkiStatus == NULL) {
		BIO_printf(bio_err, "no pkiStatus returned\n");
		exit(1);
	}

	switch (atoi(scep.reply.pkiStatus)) {
	case PKI_SUCCESS:
		/* Success						*/
		scep.clientcert = extract_cert(&scep);
		if (debug)
			BIO_printf(bio_err, "%s:%d: certificate returned %p\n",
				__FILE__, __LINE__, scep.clientcert);
		if (scep.clientcert) {
			BIO	*cb;
			cb = BIO_new(BIO_s_file());
			BIO_set_fp(cb, stdout, BIO_NOCLOSE);
			PEM_write_bio_X509(cb, scep.clientcert);
			BIO_free(cb);
		}
		exit(EXIT_SUCCESS);
		break;
	case PKI_FAILURE:	/* Failure				*/
		if (debug)
			BIO_printf(bio_err, "%s:%d: request failed: %s\n",
				__FILE__, __LINE__, scep.reply.failinfo);
		exit(1);
		break;
	case PKI_PENDING:	/* Pending				*/
		if (debug)
			BIO_printf(bio_err, "%s:%d: request still pending\n",
				__FILE__, __LINE__);
		exit(2);
		break;
	}

	/* error return							*/
err:
	ERR_print_errors(bio_err);
	exit(EXIT_FAILURE);
}
Пример #7
0
int RAND_write_file(const char *file)
	{
	unsigned char buf[BUFSIZE];
	int i,ret=0,rand_err=0;
	FILE *out = NULL;
	int n;
	
#if defined(O_CREAT) && !defined(WIN32)
	/* For some reason Win32 can't write to files created this way */
	
	/* chmod(..., 0600) is too late to protect the file,
	 * permissions should be restrictive from the start */
	int fd = open(file, O_CREAT, 0600);
	if (fd != -1)
		out = fdopen(fd, "wb");
#endif
	if (out == NULL)
		out = fopen(file,"wb");
	if (out == NULL) goto err;

#ifndef NO_CHMOD
	chmod(file,0600);
#endif
	n=RAND_DATA;
	for (;;)
		{
		i=(n > BUFSIZE)?BUFSIZE:n;
		n-=BUFSIZE;
		if (RAND_bytes(buf,i) <= 0)
			rand_err=1;
		i=fwrite(buf,1,i,out);
		if (i <= 0)
			{
			ret=0;
			break;
			}
		ret+=i;
		if (n <= 0) break;
                }
#ifdef VMS
	/* Try to delete older versions of the file, until there aren't
	   any */
	{
	char *tmpf;

	tmpf = OPENSSL_malloc(strlen(file) + 4);  /* to add ";-1" and a nul */
	if (tmpf)
		{
		strcpy(tmpf, file);
		strcat(tmpf, ";-1");
		while(delete(tmpf) == 0)
			;
		rename(file,";1"); /* Make sure it's version 1, or we
				      will reach the limit (32767) at
				      some point... */
		}
	}
#endif /* VMS */

	fclose(out);
	memset(buf,0,BUFSIZE);
err:
	return (rand_err ? -1 : ret);
	}
Пример #8
0
void LLSecAPIBasicHandler::_writeProtectedData()
{	
	std::ostringstream formatted_data_ostream;
	U8 salt[STORE_SALT_SIZE];
	U8 buffer[BUFFER_READ_SIZE];
	U8 encrypted_buffer[BUFFER_READ_SIZE];

	
	if(mProtectedDataMap.isUndefined())
	{
		LLFile::remove(mProtectedDataFilename);
		return;
	}
	// create a string with the formatted data.
	LLSDSerialize::toXML(mProtectedDataMap, formatted_data_ostream);
	std::istringstream formatted_data_istream(formatted_data_ostream.str());
	// generate the seed
	RAND_bytes(salt, STORE_SALT_SIZE);

	
	// write to a temp file so we don't clobber the initial file if there is
	// an error.
	std::string tmp_filename = mProtectedDataFilename + ".tmp";
	
	llofstream protected_data_stream(tmp_filename.c_str(), 
										llofstream::binary);
	try
	{
		
		EVP_CIPHER_CTX ctx;
		EVP_CIPHER_CTX_init(&ctx);
		EVP_EncryptInit(&ctx, EVP_rc4(), salt, NULL);
		unsigned char unique_id[MAC_ADDRESS_BYTES];
        LLMachineID::getUniqueID(unique_id, sizeof(unique_id));
		LLXORCipher cipher(unique_id, sizeof(unique_id));
		cipher.encrypt(salt, STORE_SALT_SIZE);
		protected_data_stream.write((const char *)salt, STORE_SALT_SIZE);

		while (formatted_data_istream.good())
		{
			formatted_data_istream.read((char *)buffer, BUFFER_READ_SIZE);
			if(formatted_data_istream.gcount() == 0)
			{
				break;
			}
			int encrypted_length;
			EVP_EncryptUpdate(&ctx, encrypted_buffer, &encrypted_length, 
						  buffer, formatted_data_istream.gcount());
			protected_data_stream.write((const char *)encrypted_buffer, encrypted_length);
		}
		
		// no EVP_EncrypteFinal, as this is a stream cipher
		EVP_CIPHER_CTX_cleanup(&ctx);

		protected_data_stream.close();
	}
	catch (...)
	{
		// it's good practice to clean up any secure information on error
		// (even though this file isn't really secure.  Perhaps in the future
		// it may be, however.
		LLFile::remove(tmp_filename);
		throw LLProtectedDataException("Error writing Protected Data Store");
	}

	// move the temporary file to the specified file location.
	if((((LLFile::isfile(mProtectedDataFilename) != 0) && 
		 (LLFile::remove(mProtectedDataFilename) != 0))) || 
	   (LLFile::rename(tmp_filename, mProtectedDataFilename)))
	{
		LLFile::remove(tmp_filename);
		throw LLProtectedDataException("Could not overwrite protected data store");
	}
}
Пример #9
0
int neverbleed_init(neverbleed_t *nb, char *errbuf)
{
    int pipe_fds[2] = {-1, -1}, listen_fd = -1;
    char *tempdir = NULL;

    const RSA_METHOD *default_method = RSA_PKCS1_SSLeay();
    rsa_method.rsa_pub_enc = default_method->rsa_pub_enc;
    rsa_method.rsa_pub_dec = default_method->rsa_pub_dec;
    rsa_method.rsa_verify = default_method->rsa_verify;

    /* setup the daemon */
    if (pipe(pipe_fds) != 0) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "pipe(2) failed:%s", strerror(errno));
        goto Fail;
    }
    fcntl(pipe_fds[1], F_SETFD, O_CLOEXEC);
    if ((tempdir = strdup("/tmp/openssl-privsep.XXXXXX")) == NULL) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "no memory");
        goto Fail;
    }
    if (mkdtemp(tempdir) == NULL) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to create temporary directory under /tmp:%s", strerror(errno));
        goto Fail;
    }
    memset(&nb->sun_, 0, sizeof(nb->sun_));
    nb->sun_.sun_family = AF_UNIX;
    snprintf(nb->sun_.sun_path, sizeof(nb->sun_.sun_path), "%s/_", tempdir);
    RAND_bytes(nb->auth_token, sizeof(nb->auth_token));
    if ((listen_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "socket(2) failed:%s", strerror(errno));
        goto Fail;
    }
    if (bind(listen_fd, (void *)&nb->sun_, sizeof(nb->sun_)) != 0) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to bind to %s:%s", nb->sun_.sun_path, strerror(errno));
        goto Fail;
    }
    if (listen(listen_fd, SOMAXCONN) != 0) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "listen(2) failed:%s", strerror(errno));
        goto Fail;
    }
    switch (fork()) {
    case -1:
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "fork(2) failed:%s", strerror(errno));
        goto Fail;
    case 0:
        close(pipe_fds[1]);
#ifdef __linux__
        prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
#endif
        memcpy(daemon_auth_token, nb->auth_token, NEVERBLEED_AUTH_TOKEN_SIZE);
        daemon_main(listen_fd, pipe_fds[0], tempdir);
        break;
    default:
        break;
    }
    close(listen_fd);
    listen_fd = -1;
    close(pipe_fds[0]);
    pipe_fds[0] = -1;

    /* setup engine */
    if ((nb->engine = ENGINE_new()) == NULL ||
        !ENGINE_set_id(nb->engine, "neverbleed") ||
        !ENGINE_set_name(nb->engine, "privilege separation software engine") ||
        !ENGINE_set_RSA(nb->engine, &rsa_method)) {
        snprintf(errbuf, NEVERBLEED_ERRBUF_SIZE, "failed to initialize the OpenSSL engine");
        goto Fail;
    }
    ENGINE_add(nb->engine);

    /* setup thread key */
    pthread_key_create(&nb->thread_key, dispose_thread_data);

    free(tempdir);
    return 0;
Fail:
    if (pipe_fds[0] != -1)
        close(pipe_fds[0]);
    if (pipe_fds[1] != -1)
        close(pipe_fds[1]);
    if (tempdir != NULL) {
        unlink_dir(tempdir);
        free(tempdir);
    }
    if (listen_fd != -1)
        close(listen_fd);
    if (nb->engine != NULL) {
        ENGINE_free(nb->engine);
        nb->engine = NULL;
    }
    return -1;
}
Пример #10
0
static void parse_options(struct ts *ts, int argc, char **argv) {
	int j, i, ca_err = 0, server_err = 1, input_addr_err = 0, output_addr_err = 0, ident_err = 0, port_set = 0;
	while ((j = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
		if (j == '?')
			exit(EXIT_FAILURE);
		switch (j) {
			case 'i': // -- ident
				ts->ident = optarg;
				break;
			case 'd': // --daemon
				ts->pidfile = optarg;
				break;
			case 'N': // --notify-program
				ts->notify_program = optarg;
				break;

			case 'S': // --syslog
				ts->syslog_active = 1;
				ts->syslog_remote = 0;
				break;
			case 'l': // --syslog-host
				ts->syslog_host = optarg;
				ts->syslog_active = 1;
				ts->syslog_remote = 1;
				break;
			case 'L': // --syslog-port
				ts->syslog_port = atoi(optarg);
				break;
			case 'F': // --log-file
				log_filename = optarg;
				break;

			case 'I': // --input
				input_addr_err = !parse_io_param(&ts->input, optarg, O_RDONLY, 0);
				break;
			case '1': // --input-source
				if (!inet_aton(optarg, &ts->input.isrc)) {
					fprintf(stderr, "ERROR: Can't parse input-source IP address: %s\n", optarg);
					exit(EXIT_FAILURE);
				}
				break;
			case 'R': // --input-rtp
				ts->rtp_input = !ts->rtp_input;
				break;
			case 'z': // --input-ignore-disc
				ts->ts_discont = !ts->ts_discont;
				break;
			case 'M': // --input-service
				ts->forced_service_id = strtoul(optarg, NULL, 0) & 0xffff;
				break;
			case 'T': // --input-buffer
				ts->input_buffer_time = strtoul(optarg, NULL, 0);
				break;
			case 'W': // --input-dump
				ts->input_dump_filename = optarg;
				break;

			case 'O': // --output
				output_addr_err = !parse_io_param(&ts->output, optarg,
					O_CREAT | O_WRONLY | O_TRUNC,
					S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
				break;
			case 'o': // --output-intf
				if (strchr(optarg, '.'))
					inet_aton(optarg, &ts->output.intf);
				else
					ts->output.v6_if_index = atoi(optarg);
				break;
			case 't': // --output-ttl
				ts->output.ttl = atoi(optarg);
				break;
			case 'r': // --output-rtp
				ts->rtp_output = 1;
				break;
			case 'k': // --output-rtp-ssrc
				ts->rtp_ssrc = strtoul(optarg, NULL, 0);
				break;
			case 'g': // --output-tos
				ts->output.tos = (uint8_t)strtol(optarg, NULL, 0);
				break;
			case 'u': // --no-output-on-error
				ts->no_output_on_error = !ts->no_output_on_error;
				break;
			case 'p': // --no-output-filter
				ts->pid_filter = !ts->pid_filter;
				break;
			case 'y': // --output-nit-pass
				ts->nit_passthrough = !ts->nit_passthrough;
				break;
			case 'w': // --output-eit-pass
				ts->eit_passthrough = !ts->eit_passthrough;
				break;
			case 'x': // --output-tdt-pass
				ts->tdt_passthrough = !ts->tdt_passthrough;
				break;
			case 'c': // --ca-system
				if (strcasecmp("IRDETO", optarg) == 0)
					ts->req_CA_sys = CA_IRDETO;
				else if (strcasecmp("CONNAX", optarg) == 0 || strcasecmp("CONAX", optarg) == 0)
					ts->req_CA_sys = CA_CONAX;
				else if (strcasecmp("CRYPTOWORKS", optarg) == 0)
					ts->req_CA_sys = CA_CRYPTOWORKS;
				else if (strcasecmp("SECA", optarg) == 0 || strcasecmp("MEDIAGUARD", optarg) == 0)
					ts->req_CA_sys = CA_SECA;
				else if (strcasecmp("VIACCESS", optarg) == 0)
					ts->req_CA_sys = CA_VIACCESS;
				else if (strcasecmp("VIDEOGUARD", optarg) == 0 || strcasecmp("NDS", optarg) == 0)
					ts->req_CA_sys = CA_VIDEOGUARD;
				else if (strcasecmp("NAGRA", optarg) == 0)
					ts->req_CA_sys = CA_NAGRA;
				else if (strcasecmp("DRE-CRYPT", optarg) == 0 || strcasecmp("DRECRYPT", optarg) == 0)
					ts->req_CA_sys = CA_DRECRYPT;
				else if (strcasecmp("BULCRYPT", optarg) == 0)
					ts->req_CA_sys = CA_BULCRYPT;
				else if (strcasecmp("GRIFFIN", optarg) == 0)
					ts->req_CA_sys = CA_GRIFFIN;
				else if (strcasecmp("DGCRYPT", optarg) == 0)
					ts->req_CA_sys = CA_DGCRYPT;
				else
					ca_err = 1;
				break;
			case 'C': // --caid
				ts->forced_caid = strtoul(optarg, NULL, 0) & 0xffff;
				break;
			case 'Y': // --const-cw
				ts->camd.constant_codeword = 1;
				if (strlen(optarg) > 2 && optarg[0] == '0' && optarg[1] == 'x')
					optarg += 2;
				if (strlen(optarg) != CODEWORD_LENGTH * 2) {
					fprintf(stderr, "ERROR: Constant code word should be %u characters long.\n", CODEWORD_LENGTH * 2);
					exit(EXIT_FAILURE);
				}
				if (decode_hex_string(optarg, ts->camd.key->cw, strlen(optarg)) < 0) {
					fprintf(stderr, "ERROR: Invalid hex string for constant code word: %s\n", optarg);
					exit(EXIT_FAILURE);
				}
				camd_set_cw(ts, ts->camd.key->cw, 0);
				ts->camd.key->is_valid_cw = 1;
				break;
			case 'Q': // --biss-key
				ts->camd.constant_codeword = 1;
				if (strlen(optarg) > 2 && optarg[0] == '0' && optarg[1] == 'x')
					optarg += 2;
				uint8_t *key = ts->camd.key->cw;
				// Sometimes the BISS keys are entered with their checksums already calculated (16 symbols, 8 bytes)
				// This is the same as constant cw with the same key for even and odd
				if (strlen(optarg) == (BISSKEY_LENGTH + 2) * 2) {
					if (decode_hex_string(optarg, key, strlen(optarg)) < 0) {
						fprintf(stderr, "ERROR: Invalid hex string for BISS key: %s\n", optarg);
						exit(EXIT_FAILURE);
					}
				} else {
					// BISS key without checksum (12 symbols, 6 bytes)
					if (strlen(optarg) != BISSKEY_LENGTH * 2) {
						fprintf(stderr, "ERROR: BISS key should be %u characters long.\n", BISSKEY_LENGTH * 2);
						exit(EXIT_FAILURE);
					}
					if (decode_hex_string(optarg, key, strlen(optarg)) < 0) {
						fprintf(stderr, "ERROR: Invalid hex string for BISS key: %s\n", optarg);
						exit(EXIT_FAILURE);
					}
					// Calculate BISS KEY crc
					memmove(key + 4, key + 3, 3);
					key[3] = (uint8_t)(key[0] + key[1] + key[2]);
					key[7] = (uint8_t)(key[4] + key[5] + key[6]);
				}
				// Even and odd keys are the same
				memcpy(key + 8, key, 8);
				camd_set_cw(ts, ts->camd.key->cw, 0);
				ts->camd.key->is_valid_cw = 1;
				break;

			case 'A': // --camd-proto
				if (strcasecmp(optarg, "cs378x") == 0) {
					camd_proto_cs378x(&ts->camd.ops);
				} else if (strcasecmp(optarg, "newcamd") == 0) {
					camd_proto_newcamd(&ts->camd.ops);
				} else {
					fprintf(stderr, "Unknown CAMD protocol: %s\n", optarg);
					exit(EXIT_FAILURE);
				}
				break;
			case 's': // --camd-server
				server_err = !parse_host_and_port(optarg, &ts->camd.hostname, &ts->camd.service, &port_set);
				break;
			case 'U': // --camd-user
				if (strlen(optarg) < 64)
					ts->camd.user = optarg;
				break;
			case 'P': // --camd-pass
				ts->camd.pass = optarg;
				break;
			case 'B': // --camd-des-key
				if (strlen(optarg) > 2 && optarg[0] == '0' && optarg[1] == 'x')
					optarg += 2;
				if (strlen(optarg) != DESKEY_LENGTH) {
					fprintf(stderr, "ERROR: des key should be %u characters long.\n", DESKEY_LENGTH);
					exit(EXIT_FAILURE);
				}
				strncpy(ts->camd.newcamd.hex_des_key, optarg, sizeof(ts->camd.newcamd.hex_des_key) - 1);
				ts->camd.newcamd.hex_des_key[sizeof(ts->camd.newcamd.hex_des_key) - 1] = 0;
				break;
			case '4': // --ipv4
				ai_family = AF_INET;
				break;
			case '6': // --ipv6
				ai_family = AF_INET6;
				break;

			case 'e': // --emm
				ts->process_emm = !ts->process_emm;
				break;
			case 'Z': // --emm-pid
				ts->forced_emm_pid = strtoul(optarg, NULL, 0) & 0x1fff;
				break;
			case 'E': // --emm-only
				ts->process_emm = 1;
				ts->process_ecm = 0;
				ts->output_stream = 0;
				break;
			case 'f': // --emm-report-time
				ts->emm_report_interval = strtoul(optarg, NULL, 10);
				if (ts->emm_report_interval > 86400)
					ts->emm_report_interval = 86400;
				break;

			case 'a': // --emm-filter
				if (ts->emm_filters_num + 1 > MAX_FILTERS) {
					fprintf(stderr, "ERROR: Maximum allowed filters are %d.\n", MAX_FILTERS);
					exit(EXIT_FAILURE);
				}
				if (filter_parse(optarg, &ts->emm_filters[ts->emm_filters_num])) {
					ts->emm_filters_num++;
				} else {
					fprintf(stderr, "ERROR: Can't parse EMM filter: %s\n", optarg);
					exit(EXIT_FAILURE);
				}
				break;

			case 'X': // --ecm-pid
				ts->forced_ecm_pid = strtoul(optarg, NULL, 0) & 0x1fff;
				break;
			case 'v': // --ecm-only
				ts->process_emm = 0;
				ts->process_ecm = 1;
				ts->output_stream = 0;
				break;
			case 'H': // --ecm-report-time
				ts->ecm_report_interval = strtoul(optarg, NULL, 10);
				if (ts->ecm_report_interval > 86400)
					ts->ecm_report_interval = 86400;
				break;
			case 'G': // --ecm-irdeto-type
				ts->irdeto_ecm_idx = strtoul(optarg, NULL, 0);
				ts->irdeto_ecm_filter_type = IRDETO_FILTER_IDX;
				break;
			case '2': // --ecm-irdeto-chid
				ts->irdeto_ecm_chid = strtoul(optarg, NULL, 0);
				ts->irdeto_ecm_filter_type = IRDETO_FILTER_CHID;
				break;
			case 'K': // --ecm-no-log
				ts->ecm_cw_log = !ts->ecm_cw_log;
				break;
			case 'J': // --cw-warn-time
				ts->cw_warn_sec = strtoul(optarg, NULL, 10);
				if (ts->cw_warn_sec > 86400)
					ts->cw_warn_sec = 86400;
				ts->cw_last_warn= ts->cw_last_warn + ts->cw_warn_sec;
				break;
			case 'q': // --ecm-and-emm-only
				ts->process_emm = 1;
				ts->process_ecm = 1;
				ts->output_stream = 0;
				break;

			case 'D': // --debug
				ts->debug_level = atoi(optarg);
				if (ts->debug_level > 0)
					ts->pid_report = 1;
				break;
			case 'j': // --pid-report
				ts->pid_report = 1;
				break;
			case 'b': // --bench
				csa_benchmark();
				exit(EXIT_SUCCESS);

			case 'n': // --ecm-file
			case 'm': // --emm-file
				packet_from_file = 1;
				packet_buflen = file_hex2buf(optarg, packet_buf, sizeof(packet_buf));
				if (!packet_buflen) {
					fprintf(stderr, "ERROR: Can't init packet from file.\n");
					exit(1);
				}
				packet_type = j == 'n' ? ECM_MSG : EMM_MSG;
				break;

			case 'h': // --help
				show_help(ts);
				exit(EXIT_SUCCESS);

			case 'V': // --version
				printf("%s\n", program_id);
				exit(EXIT_SUCCESS);
		}
	}
	if (!ts->ident) {
		if (ts->syslog_active || ts->notify_program)
			ident_err = 1;
	}

	if (packet_from_file) {
		int err = 0;
		if (!ts->forced_caid) {
			fprintf(stderr, "ERROR: CAID was not set. Use --caid option.\n");
			err++;
		}
		if (!ts->forced_service_id) {
			fprintf(stderr, "ERROR: Service id was not set. Use --input-service option.\n");
			err++;
		}
		if (err)
			exit(EXIT_FAILURE);

		ts->threaded = 0;
		input_addr_err = 0;
		output_addr_err = 0;
		ts->input.type = FILE_IO;
		ts->input.fd = 0;
		ts->output.type = FILE_IO;
		ts->output.fd = 1;
		ts->pid_filter = 0;
		ts->process_ecm = 0;
		ts->process_emm = 0;
		ts->output_stream = 0;
		ts->camd.no_reconnect = 1;
		ts->camd.check_emm_errors = 1;
		ts->emm_filters_num = 0;
	}

	// Constant codeword is special. Disable conflicting options
	if (ts->camd.constant_codeword) {
		server_err = 0; // No server settings are required
		ts->process_ecm = 0;
		ts->process_emm = 0;
		ts->output_stream = 1;
	}

	if (ident_err || ca_err || server_err || input_addr_err || output_addr_err || ts->input.type == WTF_IO || ts->output.type == WTF_IO) {
		show_help(ts);
		if (ident_err)
			fprintf(stderr, "ERROR: Ident is not set, please use --ident option.\n");
		if (ca_err)
			fprintf(stderr, "ERROR: Requested CA system is unsupported.\n");
		if (server_err)
			fprintf(stderr, "ERROR: CAMD server address is not set or it is invalid.\n");
		if (input_addr_err)
			fprintf(stderr, "ERROR: Input address is invalid.\n");
		if (output_addr_err)
			fprintf(stderr, "ERROR: Output address is invalid.\n");
		exit(EXIT_FAILURE);
	}
	if (decode_hex_string(ts->camd.newcamd.hex_des_key, ts->camd.newcamd.bin_des_key, DESKEY_LENGTH) < 0) {
		fprintf(stderr, "ERROR: Invalid hex string for des key: %s\n", ts->camd.newcamd.hex_des_key);
		exit(EXIT_FAILURE);
	}
	if (ts->camd.ops.proto == CAMD_NEWCAMD && !port_set) {
		fprintf(stderr, "ERROR: CAMD server port is not set. Use --camd-server %s:xxxx to set the port.\n", ts->camd.hostname);
		exit(EXIT_FAILURE);
	}

	if (log_filename) {
		log_file = fopen(log_filename, "a");
		if (!log_file) {
			fprintf(stderr, "ERROR: Can't open log file %s: %s\n", log_filename, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	if (ts->ident)
		ts_LOGf("Ident      : %s\n", ts->ident);
	if (ts->notify_program)
		ts_LOGf("Notify prg : %s\n", ts->notify_program);
	if (ts->pidfile)
		ts_LOGf("Daemonize  : %s pid file.\n", ts->pidfile);
	if (ts->syslog_active) {
		if (ts->syslog_remote)
			ts_LOGf("Syslog     : %s:%d\n", ts->syslog_host, ts->syslog_port);
		else
			ts_LOGf("Syslog     : enabled\n");
	} else {
		if (!packet_from_file)
			ts_LOGf("Syslog     : disabled\n");
	}

	if (!ts->camd.constant_codeword) {
		if (ts->forced_caid)
			ts->req_CA_sys = ts_get_CA_sys(ts->forced_caid);
		if (!ts->forced_caid)
			ts_LOGf("CA System  : %s\n", ts_get_CA_sys_txt(ts->req_CA_sys));
		else
			ts_LOGf("CA System  : %s | CAID: 0x%04x (%d)\n",
				ts_get_CA_sys_txt(ts->req_CA_sys),
				ts->forced_caid, ts->forced_caid);
	} else {
		char cw_even[64], cw_odd[64];
		ts_hex_dump_buf(cw_even, sizeof(cw_even), ts->key.cw    , 8, 0);
		ts_hex_dump_buf(cw_odd , sizeof(cw_odd ), ts->key.cw + 8, 8, 0);
		ts_LOGf("Constant CW: even = %s\n", cw_even);
		ts_LOGf("Constant CW: odd  = %s\n", cw_odd);
	}

	if (ts->input.type == NET_IO) {
		ts_LOGf("Input addr : %s://%s:%s/\n",
			ts->rtp_input ? "rtp" : "udp",
			ts->input.hostname, ts->input.service);
		ts_LOGf("Input src  : %s\n", inet_ntoa(ts->input.isrc));
		if (ts->input_buffer_time) {
			ts_LOGf("Input buff : %u ms\n", ts->input_buffer_time);
		}
	} else if (ts->input.type == FILE_IO) {
		if (!packet_from_file)
			ts_LOGf("Input file : %s\n", ts->input.fd == 0 ? "STDIN" : ts->input.fname);
	}
	if (ts->input_dump_filename) {
		ts->input_dump_file = fopen(ts->input_dump_filename, "w");
		if (ts->input_dump_file)
			ts_LOGf("Input dump : %s\n", ts->input_dump_filename);
		else
			ts_LOGf("Input dump : %s | ERROR: %s\n", ts->input_dump_filename, strerror(errno));
	}
	if (ts->forced_service_id)
		ts_LOGf("Service id : 0x%04x (%d)\n",
			ts->forced_service_id, ts->forced_service_id);
	if (ts->req_CA_sys == CA_IRDETO) {
		switch (ts->irdeto_ecm_filter_type) {
		case IRDETO_FILTER_IDX : ts_LOGf("Irdeto ECM : Index: 0x%02x (%d)\n", ts->irdeto_ecm_idx, ts->irdeto_ecm_idx); break;
		case IRDETO_FILTER_CHID: ts_LOGf("Irdeto ECM : CHID: 0x%04x (%d)\n", ts->irdeto_ecm_chid, ts->irdeto_ecm_chid); break;
		}
	}

	if (ts->output_stream) {
		if (ts->output.type == NET_IO) {
			ts_LOGf("Output addr: %s://%s:%s/\n",
				ts->rtp_output ? "rtp" : "udp",
				ts->output.hostname, ts->output.service);
			ts_LOGf("Output intf: %s (IPv6 intf index:%d)\n",
				inet_ntoa(ts->output.intf), ts->output.v6_if_index);
			ts_LOGf("Output ttl : %d\n", ts->output.ttl);
			if (ts->output.tos > -1)
				ts_LOGf("Output TOS : %u (0x%02x)\n", ts->output.tos, ts->output.tos);
			if (ts->rtp_output) {
				ts_LOGf("RTP SSRC   : %u (0x%04x)\n",
					ts->rtp_ssrc, ts->rtp_ssrc);
				// It is recommended that RTP seqnum starts with random number
				RAND_bytes((unsigned char *)&(ts->rtp_seqnum), 2);
			}
		} else if (ts->output.type == FILE_IO) {
			ts_LOGf("Output file: %s\n", ts->output.fd == 1 ? "STDOUT" : ts->output.fname);
		}
		ts_LOGf("Out filter : %s (%s)%s\n",
			ts->pid_filter ? "enabled" : "disabled",
			ts->pid_filter ? "output only service related PIDs" : "output everything",
			ts->no_output_on_error ? " (No output on CW error)" : ""
		);
		if (ts->pid_filter) {
			if (ts->nit_passthrough)
				ts_LOGf("Out filter : Pass through NIT.\n");
			if (ts->eit_passthrough)
				ts_LOGf("Out filter : Pass through EIT (EPG).\n");
			if (ts->tdt_passthrough)
				ts_LOGf("Out filter : Pass through TDT/TOT.\n");
		}
		ts_LOGf("TS discont : %s\n", ts->ts_discont ? "report" : "ignore");
		ts->threaded = !(ts->input.type == FILE_IO && ts->input.fd != 0);
		ts_LOGf("Decoding   : %s\n", ts->threaded ? "threaded" : "single thread");
	} else {
		ts_LOGf("Decoding   : disabled\n");
	}

	if (!ts->camd.constant_codeword) {
		ts_LOGf("CAMD proto : %s\n", ts->camd.ops.ident);
		ts_LOGf("CAMD addr  : %s:%s%s\n", ts->camd.hostname, ts->camd.service,
			ai_family == AF_INET  ? " (IPv4 only)" :
			ai_family == AF_INET6 ? " (IPv6 only)" :
			" (IPv4/IPv6)"
		);
		ts_LOGf("CAMD user  : %s\n", ts->camd.user);
		ts_LOGf("CAMD pass  : %s\n", ts->camd.pass);
		if (ts->camd.ops.proto == CAMD_NEWCAMD)
			ts_LOGf("CAMD deskey: %s\n", ts->camd.newcamd.hex_des_key);
	}

	if (!packet_from_file)
		ts_LOGf("EMM process: %s\n", ts->process_emm ? "Yes" : "No");

	if (ts->process_emm) {
		if (ts->forced_emm_pid)
			ts_LOGf("EMM pid    : 0x%04x (%d)\n", ts->forced_emm_pid, ts->forced_emm_pid);

		if (ts->emm_report_interval)
			ts_LOGf("EMM report : %d sec\n", ts->emm_report_interval);
		else
			ts_LOGf("EMM report : disabled\n");

		for (i = 0; i < ts->emm_filters_num; i++) {
			char tmp[512];
			filter_dump(&ts->emm_filters[i], tmp, sizeof(tmp));
			ts_LOGf("EMM filter : [%2d] %s\n", i + 1,  tmp);
		}
	}

	if (!packet_from_file)
		ts_LOGf("ECM process: %s\n", ts->process_ecm ? "Yes" : "No");

	if (ts->process_ecm) {
		if (ts->forced_ecm_pid)
			ts_LOGf("ECM pid    : 0x%04x (%d)\n", ts->forced_ecm_pid, ts->forced_ecm_pid);

		if (ts->ecm_report_interval)
			ts_LOGf("ECM report : %d sec\n", ts->emm_report_interval);
		else
			ts_LOGf("ECM report : disabled\n");

		if (ts->cw_warn_sec)
			ts_LOGf("CW warning : %d sec\n", ts->cw_warn_sec);
		else
			ts_LOGf("CW warning : disabled\n");

		if (!ts->ecm_cw_log)
			ts_LOGf("ECM/CW log : disabled\n");
	}

	if (ts->ident) {
		int len = strlen(ts->ident);
		for (i = 0; i < len; i++) {
			if (ts->ident[i] == '/')
				ts->ident[i] = '-';
		}
	}
}
Пример #11
0
static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
	{
	unsigned char *buf=NULL;
	int ret=0,bit,bytes,mask;
	time_t tim;

	if (bits == 0)
		{
		BN_zero(rnd);
		return 1;
		}

	bytes=(bits+7)/8;
	bit=(bits-1)%8;
	mask=0xff<<(bit+1);

	buf=(unsigned char *)OPENSSL_malloc(bytes);
	if (buf == NULL)
		{
		BNerr(BN_F_BNRAND,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	/* make a random number and set the top and bottom bits */
	time(&tim);
	RAND_add(&tim,sizeof(tim),0.0);

	if (pseudorand)
		{
		if (RAND_pseudo_bytes(buf, bytes) == -1)
			goto err;
		}
	else
		{
		if (RAND_bytes(buf, bytes) <= 0)
			goto err;
		}

#if 1
	if (pseudorand == 2)
		{
		/* generate patterns that are more likely to trigger BN
		   library bugs */
		int i;
		unsigned char c;

		for (i = 0; i < bytes; i++)
			{
			RAND_pseudo_bytes(&c, 1);
			if (c >= 128 && i > 0)
				buf[i] = buf[i-1];
			else if (c < 42)
				buf[i] = 0;
			else if (c < 84)
				buf[i] = 255;
			}
		}
#endif

	if (top != -1)
		{
		if (top)
			{
			if (bit == 0)
				{
				buf[0]=1;
				buf[1]|=0x80;
				}
			else
				{
				buf[0]|=(3<<(bit-1));
				}
			}
		else
			{
			buf[0]|=(1<<bit);
			}
		}
	buf[0] &= ~mask;
	if (bottom) /* set bottom bit if requested */
		buf[bytes-1]|=1;
	if (!BN_bin2bn(buf,bytes,rnd)) goto err;
	ret=1;
err:
	if (buf != NULL)
		{
		OPENSSL_cleanse(buf,bytes);
		OPENSSL_free(buf);
		}
	bn_check_top(rnd);
	return(ret);
	}
Пример #12
0
void HC_DEPRECATED
DES_generate_random_block(DES_cblock *block)
{
    RAND_bytes(block, sizeof(*block));
}
Пример #13
0
void HC_DEPRECATED
DES_rand_data(void *outdata, int size)
{
    RAND_bytes(outdata, size);
}
Пример #14
0
int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
			const unsigned char *mHash,
			const EVP_MD *Hash, int sLen)
	{
	int i;
	int ret = 0;
	int hLen, maskedDBLen, MSBits, emLen;
	unsigned char *H, *salt = NULL, *p;
	EVP_MD_CTX ctx;

	hLen = EVP_MD_size(Hash);
	/*
	 * Negative sLen has special meanings:
	 *	-1	sLen == hLen
	 *	-2	salt length is maximized
	 *	-N	reserved
	 */
	if      (sLen == -1)	sLen = hLen;
	else if (sLen == -2)	sLen = -2;
	else if (sLen < -2)
		{
		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
		goto err;
		}

	MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
	emLen = RSA_size(rsa);
	if (MSBits == 0)
		{
		*EM++ = 0;
		emLen--;
		}
	if (sLen == -2)
		{
		sLen = emLen - hLen - 2;
		}
	else if (emLen < (hLen + sLen + 2))
		{
		RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
		   RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
		goto err;
		}
	if (sLen > 0)
		{
		salt = OPENSSL_malloc(sLen);
		if (!salt)
			{
			RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
		   		ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (!RAND_bytes(salt, sLen))
			goto err;
		}
	maskedDBLen = emLen - hLen - 1;
	H = EM + maskedDBLen;
	EVP_MD_CTX_init(&ctx);
	EVP_DigestInit_ex(&ctx, Hash, NULL);
	EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes);
	EVP_DigestUpdate(&ctx, mHash, hLen);
	if (sLen)
		EVP_DigestUpdate(&ctx, salt, sLen);
	EVP_DigestFinal(&ctx, H, NULL);
	EVP_MD_CTX_cleanup(&ctx);

	/* Generate dbMask in place then perform XOR on it */
	PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash);

	p = EM;

	/* Initial PS XORs with all zeroes which is a NOP so just update
	 * pointer. Note from a test above this value is guaranteed to
	 * be non-negative.
	 */
	p += emLen - sLen - hLen - 2;
	*p++ ^= 0x1;
	if (sLen > 0)
		{
		for (i = 0; i < sLen; i++)
			*p++ ^= salt[i];
		}
	if (MSBits)
		EM[0] &= 0xFF >> (8 - MSBits);

	/* H is already in place so just set final 0xbc */

	EM[emLen - 1] = 0xbc;

	ret = 1;

	err:
	if (salt)
		OPENSSL_free(salt);

	return ret;

	}
int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, const unsigned char *key,size_t key_len) 
	{
	GOST_KEY_TRANSPORT *gkt=NULL; 
	EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
	struct gost_pmeth_data *data = (gost_pmeth_data*)EVP_PKEY_CTX_get_data(pctx);
	const struct gost_cipher_info *param=get_encryption_params(NULL);
	unsigned char ukm[8], shared_key[32], crypted_key[44];
	int ret=0;
	int key_is_ephemeral=1;
	gost_ctx cctx;
	EVP_PKEY *sec_key=EVP_PKEY_CTX_get0_peerkey(pctx);
	if (data->shared_ukm) 
		{
		TINYCLR_SSL_MEMCPY(ukm, data->shared_ukm,8);
		} 
	else if (out) 
		{
		
		if (RAND_bytes(ukm,8)<=0)
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
				GOST_R_RANDOM_GENERATOR_FAILURE);
			return 0;
			}	
		}	
	/* Check for private key in the peer_key of context */	
	if (sec_key) 
		{
		key_is_ephemeral=0;
		if (!gost_get0_priv_key(sec_key)) 
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
			GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
			goto err;
			}	
		} 
	else 
		{
		key_is_ephemeral=1;
		if (out) 
			{
			sec_key = EVP_PKEY_new();
			EVP_PKEY_assign(sec_key,EVP_PKEY_base_id(pubk),EC_KEY_new());
			EVP_PKEY_copy_parameters(sec_key,pubk);
			if (!gost2001_keygen((EC_KEY*)EVP_PKEY_get0(sec_key))) 
				{
				goto err;
				}	
			}
		}
	if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param ==  gost_cipher_list)
		{
		param= gost_cipher_list+1;
		}	
    if (out) 
		{
		VKO_compute_key(shared_key,32,EC_KEY_get0_public_key((const EC_KEY*)EVP_PKEY_get0(pubk)),(EC_KEY*)EVP_PKEY_get0(sec_key),ukm);
		gost_init(&cctx,param->sblock);	
		keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
		}
	gkt = GOST_KEY_TRANSPORT_new();
	if (!gkt)
		{
		goto err;
		}	
	if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
			ukm,8))
		{
		goto err;
		}	
	if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
		{
		goto err;
		}
	if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
		{
		goto err;
		}
	if (key_is_ephemeral) {	
		if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?sec_key:pubk))
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
					GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
			goto err;
			}	
	}		
	ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
	gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
	if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
	if (!key_is_ephemeral)
		{
		/* Set control "public key from client certificate used" */
		if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
			{
			GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
				GOST_R_CTRL_CALL_FAILED);
			goto err;
			}
		}
	if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL))>0) ret =1;
	GOST_KEY_TRANSPORT_free(gkt);
	return ret;	
	err:		
	if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
	GOST_KEY_TRANSPORT_free(gkt);
	return -1;
	}
Пример #16
0
	void TunnelPool::TestTunnels ()
	{
		for (auto it: m_Tests)
		{
			LogPrint (eLogWarning, "Tunnels: test of tunnel ", it.first, " failed");
			// if test failed again with another tunnel we consider it failed
			if (it.second.first)
			{	
				if (it.second.first->GetState () == eTunnelStateTestFailed)
				{	
					it.second.first->SetState (eTunnelStateFailed);
					std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
					m_OutboundTunnels.erase (it.second.first);
				}
				else
					it.second.first->SetState (eTunnelStateTestFailed);
			}	
			if (it.second.second)
			{
				if (it.second.second->GetState () == eTunnelStateTestFailed)
				{	
					it.second.second->SetState (eTunnelStateFailed);
					{
						std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
						m_InboundTunnels.erase (it.second.second);
					}
					if (m_LocalDestination)
						m_LocalDestination->SetLeaseSetUpdated ();
				}	
				else
					it.second.second->SetState (eTunnelStateTestFailed);
			}	
		}
		m_Tests.clear ();
		// new tests	
		auto it1 = m_OutboundTunnels.begin ();
		auto it2 = m_InboundTunnels.begin ();
		while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ())
		{
			bool failed = false;
			if ((*it1)->IsFailed ())
			{	
				failed = true;
				it1++;
			}
			if ((*it2)->IsFailed ())
			{	
				failed = true;
				it2++;
			}
			if (!failed)
			{
 				uint32_t msgID;
				RAND_bytes ((uint8_t *)&msgID, 4);
 				m_Tests[msgID] = std::make_pair (*it1, *it2);
 				(*it1)->SendTunnelDataMsg ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (),
					CreateDeliveryStatusMsg (msgID));
				it1++; it2++;
			}	
		}
	}
Пример #17
0
int dtls1_enc(SSL *s, int send)
{
    SSL3_RECORD *rec;
    EVP_CIPHER_CTX *ds;
    unsigned long l;
    int bs,i,ii,j,k,n=0;
    const EVP_CIPHER *enc;

    if (send)
    {
        if (s->write_hash != NULL)
            n=EVP_MD_size(s->write_hash);
        ds=s->enc_write_ctx;
        rec= &(s->s3->wrec);
        if (s->enc_write_ctx == NULL)
            enc=NULL;
        else
        {
            enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
            if ( rec->data != rec->input)
                /* we can't write into the input stream */
                fprintf(stderr, "%s:%d: rec->data != rec->input\n",
                        __FILE__, __LINE__);
            else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
            {
                if (!RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)))
                    return -1;
            }
        }
    }
    else
    {
        if (s->read_hash != NULL)
            n=EVP_MD_size(s->read_hash);
        ds=s->enc_read_ctx;
        rec= &(s->s3->rrec);
        if (s->enc_read_ctx == NULL)
            enc=NULL;
        else
            enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
    }

#ifdef KSSL_DEBUG
    printf("dtls1_enc(%d)\n", send);
#endif    /* KSSL_DEBUG */

    if ((s->session == NULL) || (ds == NULL) ||
            (enc == NULL))
    {
        memmove(rec->data,rec->input,rec->length);
        rec->input=rec->data;
    }
    else
    {
        l=rec->length;
        bs=EVP_CIPHER_block_size(ds->cipher);

        if ((bs != 1) && send)
        {
            i=bs-((int)l%bs);

            /* Add weird padding of upto 256 bytes */

            /* we need to add 'i' padding bytes of value j */
            j=i-1;
            if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
            {
                if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
                    j++;
            }
            for (k=(int)l; k<(int)(l+i); k++)
                rec->input[k]=j;
            l+=i;
            rec->length+=i;
        }

#ifdef KSSL_DEBUG
        {
            unsigned long ui;
            printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
                   (void *)ds,rec->data,rec->input,l);
            printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n",
                   ds->buf_len, ds->cipher->key_len,
                   (unsigned long)DES_KEY_SZ,
                   (unsigned long)DES_SCHEDULE_SZ,
                   ds->cipher->iv_len);
            printf("\t\tIV: ");
            for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
            printf("\n");
            printf("\trec->input=");
            for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
            printf("\n");
        }
#endif	/* KSSL_DEBUG */

        if (!send)
        {
            if (l == 0 || l%bs != 0)
            {
                SSLerr(SSL_F_DTLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
                ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
                return 0;
            }
        }

        EVP_Cipher(ds,rec->data,rec->input,l);

#ifdef KSSL_DEBUG
        {
            unsigned long ki;
            printf("\trec->data=");
            for (ki=0; ki<l; ki++)
                printf(" %02x", rec->data[ki]);
            printf("\n");
        }
#endif	/* KSSL_DEBUG */

        if ((bs != 1) && !send)
        {
            ii=i=rec->data[l-1]; /* padding_length */
            i++;
            if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
            {
                /* First packet is even in size, so check */
                if ((memcmp(s->s3->read_sequence,
                            "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
                    s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
                if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
                    i--;
            }
            /* TLS 1.0 does not bound the number of padding bytes by the block size.
             * All of them must have value 'padding_length'. */
            if (i > (int)rec->length)
            {
                /* Incorrect padding. SSLerr() and ssl3_alert are done
                 * by caller: we don't want to reveal whether this is
                 * a decryption error or a MAC verification failure
                 * (see http://www.openssl.org/~bodo/tls-cbc.txt)
                 */
                return -1;
            }
            for (j=(int)(l-i); j<(int)l; j++)
            {
                if (rec->data[j] != ii)
                {
                    /* Incorrect padding */
                    return -1;
                }
            }
            rec->length-=i;

            rec->data += bs;    /* skip the implicit IV */
            rec->input += bs;
            rec->length -= bs;
        }
    }
    return(1);
}
Пример #18
0
/*
 * Wrap data in PKCS#7 envelopes and base64-encode the result.
 * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject
 * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in
 * GetCert and GETCrl.
 */
int pkcs7_wrap(struct scep *s, struct sscep_ctx *ctx, struct sscep_operation_info *op_info)
{
    BIO *databio = NULL;
    BIO *encbio = NULL;
    BIO *pkcs7bio = NULL;
    BIO *memorybio = NULL;
    BIO *outbio = NULL;
    unsigned char *buffer = NULL;
    int len = 0;
    STACK_OF(X509) *recipients = NULL;
    PKCS7 *p7enc = NULL;
    PKCS7_SIGNER_INFO *si;
    STACK_OF(X509_ATTRIBUTE) *attributes;
    X509 *signercert = NULL;
    EVP_PKEY *signerkey = NULL;
    int ret = SCEP_PKISTATUS_P7;
    char *payload = NULL;
    int payload_len;

    /* Create a new sender nonce for all messages
     * XXXXXXXXXXXXXX should it be per transaction? */
    s->sender_nonce_len = 16;
    free(s->sender_nonce);/* Clean up from previous runs */
    s->sender_nonce = (char *)malloc(s->sender_nonce_len * sizeof(char));
    RAND_bytes((unsigned char *) s->sender_nonce, s->sender_nonce_len);

    /* Prepare data payload */
    switch (s->request_type) {
        case SCEP_REQUEST_PKCSREQ:
            /*
             * Set printable message type
             * We set this later as an autheticated attribute
             * "messageType".
             */
            s->request_type_str = SCEP_REQUEST_PKCSREQ_STR;

            /* Signer cert */
            signercert = s->signercert;
            signerkey = s->signerkey;

            /* Create inner PKCS#7  */
            if (ctx->verbose){
                qeo_log_i("creating inner PKCS#7");
            }

            /* Read request in memory bio */
            databio = BIO_new(BIO_s_mem());
            if (i2d_X509_REQ_bio(databio, op_info->request) <= 0) {
                qeo_log_e("error writing certificate request in bio");
                goto error;
            }
            (void)BIO_flush(databio);
            break;

        case SCEP_REQUEST_GETCERTINIT:

            /* Set printable message type */
            s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR;

            /* Signer cert */
            signercert = s->signercert;
            signerkey = s->signerkey;

            /* Create inner PKCS#7  */
            if (ctx->verbose){
                qeo_log_i("creating inner PKCS#7");
            }

            /* Read data in memory bio */
            databio = BIO_new(BIO_s_mem());
            if (i2d_pkcs7_issuer_and_subject_bio(databio, s->ias_getcertinit)) {
                qeo_log_e("error writing GetCertInitial data in bio");
                goto error;
            }
            (void)BIO_flush(databio);
            break;
    }
    /* Below this is the common code for all request_type */

    /* Read in the payload */
    payload_len = BIO_get_mem_data(databio, &payload);
    if (ctx->verbose){
        qeo_log_i("data payload size: %d bytes", payload_len);
    }

    /* Create encryption certificate stack */
    if ((recipients = sk_X509_new(NULL) ) == NULL) {
        qeo_log_e("error creating certificate stack");
        goto error;
    }
    if (sk_X509_push(recipients, op_info->racert) <= 0) {
        qeo_log_e("error adding recipient encryption certificate");
        goto error;
    }

    /* Create BIO for encryption  */
    if ((encbio = BIO_new_mem_buf(payload, payload_len)) == NULL ) {
        qeo_log_e("error creating data bio");
        goto error;
    }

    /* Encrypt */
    if (!(p7enc = PKCS7_encrypt(recipients, encbio, ctx->enc_alg, PKCS7_BINARY))) {
        qeo_log_e("request payload encrypt failed");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("successfully encrypted payload");
    }

    /* Write encrypted data */
    memorybio = BIO_new(BIO_s_mem());
    if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) {
        qeo_log_e("error writing encrypted data");
        goto error;
    }
    (void)BIO_flush(memorybio);
    BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY);
    len = BIO_get_mem_data(memorybio, &buffer);
    BIO_free(memorybio);
    memorybio=NULL;
    if (ctx->verbose){
        qeo_log_i("envelope size: %d bytes", len);
    }
    if (ctx->debug) {
        qeo_log_i("printing PEM fomatted PKCS#7");
        PEM_write_PKCS7(stdout, p7enc);
    }

    /* Create outer PKCS#7  */
    if (ctx->verbose){
        qeo_log_i("creating outer PKCS#7");
    }
    s->request_p7 = PKCS7_new();
    if (s->request_p7 == NULL ) {
        qeo_log_e("failed creating PKCS#7 for signing");
        goto error;
    }
    if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) {
        qeo_log_e("failed setting PKCS#7 type");
        goto error;
    }

    /* Add signer certificate  and signature */
    PKCS7_add_certificate(s->request_p7, signercert);
    if ((si = PKCS7_add_signature(s->request_p7, signercert, signerkey, ctx->sig_alg)) == NULL ) {
        qeo_log_e("error adding PKCS#7 signature");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("signature added successfully");
    }

    /* Set signed attributes */
    if (ctx->verbose){
        qeo_log_i("adding signed attributes");
    }
    attributes = sk_X509_ATTRIBUTE_new_null();
    add_attribute_string(attributes, ctx->nid_transId, s->transaction_id, ctx);
    add_attribute_string(attributes, ctx->nid_messageType, s->request_type_str, ctx);
    add_attribute_octet(attributes, ctx->nid_senderNonce, s->sender_nonce, s->sender_nonce_len, ctx);
    PKCS7_set_signed_attributes(si, attributes);
    sk_X509_ATTRIBUTE_pop_free(attributes, X509_ATTRIBUTE_free);

    /* Add contentType */
    if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) {
        qeo_log_e("error adding NID_pkcs9_contentType");
        goto error;
    }

    /* Create new content */
    if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) {
        qeo_log_e("failed setting PKCS#7 content type");
        goto error;
    }

    /* Write data  */
    pkcs7bio = PKCS7_dataInit(s->request_p7, NULL );
    if (pkcs7bio == NULL ) {
        qeo_log_e("error opening bio for writing PKCS#7 data");
        goto error;
    }
    if (len != BIO_write(pkcs7bio, buffer, len)) {
        qeo_log_e("error writing PKCS#7 data");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("PKCS#7 data written successfully");
    }

    /* Finalize PKCS#7  */
    if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) {
        qeo_log_e("error finalizing outer PKCS#7");
        goto error;
    }
    if (ctx->debug) {
        qeo_log_i("printing PEM fomatted PKCS#7");
        PEM_write_PKCS7(stdout, s->request_p7);
    }

    /* base64-encode the data */
    if (ctx->verbose){
        qeo_log_i("applying base64 encoding");
    }

    /* Create base64 filtering bio */
    memorybio = BIO_new(BIO_s_mem());
    outbio = BIO_push(BIO_new(BIO_f_base64()), memorybio);

    /* Copy PKCS#7 */
    i2d_PKCS7_bio(outbio, s->request_p7);
    (void)BIO_flush(outbio);
    payload_len = BIO_get_mem_data(memorybio, &payload);
    s->request_payload = (char*) malloc(sizeof(char)*payload_len);
    if (!s->request_payload){
        goto error;
    }
    s->request_len = payload_len;
    memcpy(s->request_payload, payload, s->request_len);
    if (ctx->verbose){
        qeo_log_i("base64 encoded payload size: %d bytes", payload_len);
    }

    ret = 0;
error:
    BIO_free(databio);
    BIO_free(encbio);
    BIO_free_all(pkcs7bio);
    BIO_free(memorybio);
    BIO_free(outbio);
    if (recipients != NULL){
        sk_X509_free(recipients);/* Only free the stack, not the certificates */
    }
    PKCS7_free(p7enc);
    OPENSSL_free(buffer);
    return ret;
}
Пример #19
0
// Generate random data
bool OSSLRNG::generateRandom(ByteString& data, const size_t len)
{
	data.wipe(len);

	return RAND_bytes(&data[0], len);
}
Пример #20
0
int pkey_GOST_ECcp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out,
                           size_t *out_len, const unsigned char *key,
                           size_t key_len)
{
    GOST_KEY_TRANSPORT *gkt = NULL;
    EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
    struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
    int pkey_nid = EVP_PKEY_base_id(pubk);
    ASN1_OBJECT *crypt_params_obj = (pkey_nid == NID_id_GostR3410_2001) ?
        OBJ_nid2obj(NID_id_Gost28147_89_CryptoPro_A_ParamSet) :
        OBJ_nid2obj(NID_id_tc26_gost_28147_param_Z);
    const struct gost_cipher_info *param =
        get_encryption_params(crypt_params_obj);
    unsigned char ukm[8], shared_key[32], crypted_key[44];
    int ret = 0;
    int key_is_ephemeral = 1;
    gost_ctx cctx;
    EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx);
    if (data->shared_ukm) {
        memcpy(ukm, data->shared_ukm, 8);
    } else if (out) {

        if (RAND_bytes(ukm, 8) <= 0) {
            GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, GOST_R_RNG_ERROR);
            return 0;
        }
    }
    /* Check for private key in the peer_key of context */
    if (sec_key) {
        key_is_ephemeral = 0;
        if (!gost_get0_priv_key(sec_key)) {
            GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT,
                    GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
            goto err;
        }
    } else {
        key_is_ephemeral = 1;
        if (out) {
            sec_key = EVP_PKEY_new();
            EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), EC_KEY_new());
            EVP_PKEY_copy_parameters(sec_key, pubk);
            if (!gost_ec_keygen(EVP_PKEY_get0(sec_key))) {
                goto err;
            }
        }
    }
    if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS)
        && param == gost_cipher_list) {
        param = gost_cipher_list;
    }
    if (out) {
        int dgst_nid = NID_undef;
        EVP_PKEY_get_default_digest_nid(pubk, &dgst_nid);

        if (!VKO_compute_key(shared_key, 32,
                             EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)),
                             EVP_PKEY_get0(sec_key), ukm, dgst_nid)) {
            GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT,
                    GOST_R_ERROR_COMPUTING_SHARED_KEY);
            goto err;
        }
        gost_init(&cctx, param->sblock);
        keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key);
    }
    gkt = GOST_KEY_TRANSPORT_new();
    if (!gkt) {
        goto err;
    }
    if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) {
        goto err;
    }
    if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) {
        goto err;
    }
    if (!ASN1_OCTET_STRING_set
        (gkt->key_info->encrypted_key, crypted_key + 8, 32)) {
        goto err;
    }
    if (key_is_ephemeral) {
        if (!X509_PUBKEY_set
            (&gkt->key_agreement_info->ephem_key, out ? sec_key : pubk)) {
            GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT,
                    GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
            goto err;
        }
    }
    ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
    gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
    if (key_is_ephemeral)
        EVP_PKEY_free(sec_key);
    if (!key_is_ephemeral) {
        /* Set control "public key from client certificate used" */
        if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL)
            <= 0) {
            GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, GOST_R_CTRL_CALL_FAILED);
            goto err;
        }
    }
    if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL)) > 0)
        ret = 1;
    GOST_KEY_TRANSPORT_free(gkt);
    return ret;
 err:
    if (key_is_ephemeral)
        EVP_PKEY_free(sec_key);
    GOST_KEY_TRANSPORT_free(gkt);
    return -1;
}
Пример #21
0
static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen,
                                    size_t keylen, uint64_t N, uint64_t r,
                                    uint64_t p)
{
    X509_ALGOR *keyfunc = NULL;
    SCRYPT_PARAMS *sparam = NULL;

    sparam = SCRYPT_PARAMS_new();
    if (sparam == NULL)
        goto merr;

    if (!saltlen)
        saltlen = PKCS5_SALT_LEN;

    /* This will either copy salt or grow the buffer */
    if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0)
        goto merr;

    if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0)
        goto err;

    if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0)
        goto merr;

    if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0)
        goto merr;

    if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0)
        goto merr;

    /* If have a key len set it up */

    if (keylen > 0) {
        sparam->keyLength = ASN1_INTEGER_new();
        if (sparam->keyLength == NULL)
            goto merr;
        if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0)
            goto merr;
    }

    /* Finally setup the keyfunc structure */

    keyfunc = X509_ALGOR_new();
    if (keyfunc == NULL)
        goto merr;

    keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt);

    /* Encode SCRYPT_PARAMS into parameter of pbe2 */

    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam,
                                &keyfunc->parameter) == NULL)
        goto merr;

    SCRYPT_PARAMS_free(sparam);
    return keyfunc;

 merr:
    ASN1err(ASN1_F_PKCS5_SCRYPT_SET, ERR_R_MALLOC_FAILURE);
 err:
    SCRYPT_PARAMS_free(sparam);
    X509_ALGOR_free(keyfunc);
    return NULL;
}
Пример #22
0
static int
sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info)
{
	struct sm_cwa_session *cwa_session = &sm_info->session.cwa;
	struct sm_cwa_keyset *cwa_keyset = &sm_info->session.cwa.cwa_keyset;
	scconf_block *sm_conf_block = NULL, **blocks;
	struct sc_crt *crt_at = &sm_info->session.cwa.params.crt_at;
	const char *value = NULL;
	char name[128];
	unsigned char hex[48];
	size_t hex_len = sizeof(hex);
	int rv, ii, ref = crt_at->refs[0] & IASECC_OBJECT_REF_MAX;

	for (ii = 0; ctx->conf_blocks[ii]; ii++) {
		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[ii], "secure_messaging", sm_info->config_section);
		if (blocks) {
			sm_conf_block = blocks[0];
			free(blocks);
		}

		if (sm_conf_block)
			break;
	}

	sc_log(ctx, "CRT(algo:%X,ref:%X)", crt_at->algo, crt_at->refs[0]);
	/* Keyset ENC */
	if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL))
		snprintf(name, sizeof(name), "keyset_%s_%02i_enc",
				sc_dump_hex(sm_info->current_aid.value, sm_info->current_aid.len), ref);
	else
		snprintf(name, sizeof(name), "keyset_%02i_enc", ref);
	value = scconf_get_str(sm_conf_block, name, NULL);
	if (!value)   {
		sc_log(ctx, "No %s value in OpenSC config", name);
		return SC_ERROR_SM_KEYSET_NOT_FOUND;
	}

	sc_log(ctx, "keyset::enc(%i) %s", strlen(value), value);
	if (strlen(value) == 16)   {
		memcpy(cwa_keyset->enc, value, 16);
	}
	else   {
		hex_len = sizeof(hex);
		rv = sc_hex_to_bin(value, hex, &hex_len);
		if (rv)   {
			sc_log(ctx, "SM get %s: hex to bin failed for '%s'; error %i", name, value, rv);
			return SC_ERROR_UNKNOWN_DATA_RECEIVED;
		}

		sc_log(ctx, "ENC(%i) %s", hex_len, sc_dump_hex(hex, hex_len));
		if (hex_len != 16)
			return SC_ERROR_INVALID_DATA;

		memcpy(cwa_keyset->enc, hex, hex_len);
	}
	sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->enc, 16));

	/* Keyset MAC */
	if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL))
		snprintf(name, sizeof(name), "keyset_%s_%02i_mac",
				sc_dump_hex(sm_info->current_aid.value, sm_info->current_aid.len), ref);
	else
		snprintf(name, sizeof(name), "keyset_%02i_mac", ref);
	value = scconf_get_str(sm_conf_block, name, NULL);
	if (!value)   {
		sc_log(ctx, "No %s value in OpenSC config", name);
		return SC_ERROR_SM_KEYSET_NOT_FOUND;
	}

	sc_log(ctx, "keyset::mac(%i) %s", strlen(value), value);
	if (strlen(value) == 16)   {
		memcpy(cwa_keyset->mac, value, 16);
	}
	else   {
		hex_len = sizeof(hex);
		rv = sc_hex_to_bin(value, hex, &hex_len);
		if (rv)   {
			sc_log(ctx, "SM get '%s': hex to bin failed for '%s'; error %i", name, value, rv);
			return SC_ERROR_UNKNOWN_DATA_RECEIVED;
		}

		sc_log(ctx, "MAC(%i) %s", hex_len, sc_dump_hex(hex, hex_len));
		if (hex_len != 16)
			return SC_ERROR_INVALID_DATA;

		memcpy(cwa_keyset->mac, hex, hex_len);
	}
	sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->mac, 16));

	cwa_keyset->sdo_reference = crt_at->refs[0];


	/* IFD parameters */
	//memset(cwa_session, 0, sizeof(struct sm_cwa_session));
	value = scconf_get_str(sm_conf_block, "ifd_serial", NULL);
	if (!value)
		return SC_ERROR_SM_IFD_DATA_MISSING;
	hex_len = sizeof(hex);
	rv = sc_hex_to_bin(value, hex, &hex_len);
	if (rv)   {
		sc_log(ctx, "SM get 'ifd_serial': hex to bin failed for '%s'; error %i", value, rv);
		return SC_ERROR_UNKNOWN_DATA_RECEIVED;
	}

	if (hex_len != sizeof(cwa_session->ifd.sn))   {
		sc_log(ctx, "SM get 'ifd_serial': invalid IFD serial length: %i", hex_len);
		return SC_ERROR_UNKNOWN_DATA_RECEIVED;
	}

	memcpy(cwa_session->ifd.sn, hex, hex_len);

        rv = RAND_bytes(cwa_session->ifd.rnd, 8);
        if (!rv)   {
		sc_log(ctx, "Generate random error: %i", rv);
		return SC_ERROR_SM_RAND_FAILED;
	}

        rv = RAND_bytes(cwa_session->ifd.k, 32);
        if (!rv)   {
		sc_log(ctx, "Generate random error: %i", rv);
		return SC_ERROR_SM_RAND_FAILED;
	}
	sc_log(ctx, "IFD.Serial: %s", sc_dump_hex(cwa_session->ifd.sn, sizeof(cwa_session->ifd.sn)));
	sc_log(ctx, "IFD.Rnd: %s", sc_dump_hex(cwa_session->ifd.rnd, sizeof(cwa_session->ifd.rnd)));
	sc_log(ctx, "IFD.K: %s", sc_dump_hex(cwa_session->ifd.k, sizeof(cwa_session->ifd.k)));

	return SC_SUCCESS;
}
Пример #23
0
static int client_master_key(SSL *s)
	{
	unsigned char *buf;
	unsigned char *p,*d;
	int clear,enc,karg,i;
	SSL_SESSION *sess;
	const EVP_CIPHER *c;
	const EVP_MD *md;

	buf=(unsigned char *)s->init_buf->data;
	if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A)
		{

		if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
			{
			ssl2_return_error(s,SSL2_PE_NO_CIPHER);
			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
			return(-1);
			}
		sess=s->session;
		p=buf;
		d=p+10;
		*(p++)=SSL2_MT_CLIENT_MASTER_KEY;/* type */

		i=ssl_put_cipher_by_char(s,sess->cipher,p);
		p+=i;

		/* make key_arg data */
		i=EVP_CIPHER_iv_length(c);
		sess->key_arg_length=i;
		if (i > SSL_MAX_KEY_ARG_LENGTH)
			{
			ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
			return -1;
			}
		if (i > 0)
			if (RAND_pseudo_bytes(sess->key_arg,i) <= 0)
				return -1;

		/* make a master key */
		i=EVP_CIPHER_key_length(c);
		sess->master_key_length=i;
		if (i > 0)
			{
			if (i > (int)sizeof(sess->master_key))
				{
				ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
				SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
				return -1;
				}
			if (RAND_bytes(sess->master_key,i) <= 0)
				{
				ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
				return(-1);
				}
			}

		if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
			enc=8;
		else if (SSL_C_IS_EXPORT(sess->cipher))
			enc=5;
		else
			enc=i;

		if ((int)i < enc)
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_CIPHER_TABLE_SRC_ERROR);
			return(-1);
			}
		clear=i-enc;
		s2n(clear,p);
		memcpy(d,sess->master_key,(unsigned int)clear);
		d+=clear;

		enc=ssl_rsa_public_encrypt(sess->sess_cert,enc,
			&(sess->master_key[clear]),d,
			(s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING);
		if (enc <= 0)
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PUBLIC_KEY_ENCRYPT_ERROR);
			return(-1);
			}
#ifdef PKCS1_CHECK
		if (s->options & SSL_OP_PKCS1_CHECK_1) d[1]++;
		if (s->options & SSL_OP_PKCS1_CHECK_2)
			sess->master_key[clear]++;
#endif
		s2n(enc,p);
		d+=enc;
		karg=sess->key_arg_length;	
		s2n(karg,p); /* key arg size */
		if (karg > (int)sizeof(sess->key_arg))
			{
			ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
			SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
			return -1;
			}
		memcpy(d,sess->key_arg,(unsigned int)karg);
		d+=karg;

		s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_B;
		s->init_num=d-buf;
		s->init_off=0;
		}

	/* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */
	return(ssl2_do_write(s));
	}
Пример #24
0
int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
                                    const uint8_t *from, unsigned flen,
                                    const uint8_t *param, unsigned plen,
                                    const EVP_MD *md, const EVP_MD *mgf1md) {
  unsigned i, emlen, mdlen;
  uint8_t *db, *seed;
  uint8_t *dbmask = NULL, seedmask[EVP_MAX_MD_SIZE];
  int ret = 0;

  if (md == NULL) {
    md = EVP_sha1();
  }
  if (mgf1md == NULL) {
    mgf1md = md;
  }

  mdlen = EVP_MD_size(md);

  if (tlen < 2 * mdlen + 2) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
                      RSA_R_KEY_SIZE_TOO_SMALL);
    return 0;
  }

  emlen = tlen - 1;
  if (flen > emlen - 2 * mdlen - 1) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
                      RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
    return 0;
  }

  if (emlen < 2 * mdlen + 1) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
                      RSA_R_KEY_SIZE_TOO_SMALL);
    return 0;
  }

  to[0] = 0;
  seed = to + 1;
  db = to + mdlen + 1;

  if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) {
    return 0;
  }
  memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);
  db[emlen - flen - mdlen - 1] = 0x01;
  memcpy(db + emlen - flen - mdlen, from, flen);
  if (!RAND_bytes(seed, mdlen)) {
    return 0;
  }

  dbmask = OPENSSL_malloc(emlen - mdlen);
  if (dbmask == NULL) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
                      ERR_R_MALLOC_FAILURE);
    return 0;
  }

  if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0) {
    goto out;
  }
  for (i = 0; i < emlen - mdlen; i++) {
    db[i] ^= dbmask[i];
  }

  if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0) {
    goto out;
  }
  for (i = 0; i < mdlen; i++) {
    seed[i] ^= seedmask[i];
  }
  ret = 1;

out:
  OPENSSL_free(dbmask);
  return ret;
}
Пример #25
0
int
main() {
    BIO *bio;
    RSA *rsa=0, *rsa_pub, *rsa_priv=0;
    char buf[4096], enc[4096], dec[4096];
    BUF_MEM *ptr;
    int len, enc_len, dec_len;
    int i;
    BF_KEY key;
    char ivec_orig[8] = {1, 2, 3, 4, 5, 6, 7, 8}, ivec[8];


    do {
        //OpenSSL_add_all_algorithms();
        //OpenSSL_add_all_ciphers();
        //OpenSSL_add_all_digests();

        printf("generate_key:\n");
        rsa = RSA_generate_key(1024, 3, gen_cb, 0);
        printf("\n");

        printf("pem public key:\n");
        bio = BIO_new(BIO_s_mem());
        i = PEM_write_bio_RSAPublicKey(bio, rsa);
        BIO_flush(bio);
        i = BIO_get_mem_ptr(bio, &ptr);
        printf("pem public key len=%d\n", ptr->length);
        fwrite(ptr->data, ptr->length, 1, stdout);
        len = ptr->length;
        memcpy(buf, ptr->data, len);
        BIO_free(bio);
        printf("\n");

        bio = BIO_new_mem_buf(buf, len);
        rsa_pub = PEM_read_bio_RSAPublicKey(bio, 0, 0, 0);
        BIO_free(bio);

        printf("pem private key:\n");
        bio = BIO_new(BIO_s_mem());
        i = PEM_write_bio_RSAPrivateKey(bio, rsa, 0, 0, 0, 0, 0);
        BIO_flush(bio);
        i = BIO_get_mem_ptr(bio, &ptr);
        printf("pem private key i=%d len=%d\n", i, ptr->length);
        fwrite(ptr->data, ptr->length, 1, stdout);
        len = ptr->length;
        memcpy(buf, ptr->data, len);
        BIO_free(bio);
        printf("\n");

        bio = BIO_new_mem_buf(buf, len);
        rsa_priv = PEM_read_bio_RSAPrivateKey(bio, 0, 0, 0);
        BIO_free(bio);

        /* encrypt */

        printf("buffer:\n");
        len = sprintf(buf, "1234567890123456");
        len = 128/8;
        RAND_bytes(buf, len);
        printf("buf_len=%d\n", len);
        //printf("%s", dec);
        for(i=0; i<len; i++) {
            printf("%02x", (unsigned int)buf[i]&0xff);
        }
        printf("\n");


        printf("public_encrypt:\n");
        memset(enc, 0, sizeof(enc));
        enc_len = RSA_public_encrypt(len, buf, enc, rsa_pub, RSA_PKCS1_OAEP_PADDING);
        if( enc_len < 0 ) {
            printf("err=%ld\n", ERR_get_error());
            break;

        }
        printf("enc_len=%d\n", enc_len);
        for(i=0; i<enc_len; i++) {
            printf("%02x", (unsigned int)enc[i]&0xff);
        }
        printf("\n");


        printf("public_decrypt:\n");
        memset(dec, 0, sizeof(dec));
        dec_len = RSA_private_decrypt(enc_len, enc, dec, rsa_priv, RSA_PKCS1_OAEP_PADDING);
        if( dec_len < 0 ) {
            printf("err=%ld\n", ERR_get_error());
            break;

        }
        printf("dec_len=%d\n", dec_len);
        for(i=0; i<dec_len; i++) {
            printf("%02x", (unsigned int)dec[i]&0xff);
        }
        printf("\n");

        // blowfish
        BF_set_key(&key, dec_len, dec);

        i = 0;
        memcpy(ivec, ivec_orig, 8);
        memset(buf, 0, sizeof(buf));
        BF_cfb64_encrypt(enc, buf, enc_len, &key, ivec, &i, BF_ENCRYPT);

        printf("BF_cfb64_encrypt:\n");
        for(i=0; i<enc_len; i++) {
            printf("%02x", (unsigned int)buf[i]&0xff);
        }
        printf("\n");

        i = 0;
        memcpy(ivec, ivec_orig, 8);
        memset(enc, 0, sizeof(buf));
        BF_cfb64_encrypt(buf, enc, enc_len, &key, ivec, &i, BF_DECRYPT);

        printf("BF_cfb64_decrypt:\n");
        for(i=0; i<enc_len; i++) {
            printf("%02x", (unsigned int)enc[i]&0xff);
        }
        printf("\n");

    } while(0);

    if( rsa ) {
        RSA_free(rsa);
    }


    return 0;
}
Пример #26
0
int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
                                   const unsigned char *mHash,
                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
                                   int sLen) {
  int i;
  int ret = 0;
  size_t maskedDBLen, MSBits, emLen;
  size_t hLen;
  unsigned char *H, *salt = NULL, *p;
  EVP_MD_CTX ctx;

  if (mgf1Hash == NULL) {
    mgf1Hash = Hash;
  }

  hLen = EVP_MD_size(Hash);

  /* Negative sLen has special meanings:
   *	-1	sLen == hLen
   *	-2	salt length is maximized
   *	-N	reserved */
  if (sLen == -1) {
    sLen = hLen;
  } else if (sLen == -2) {
    sLen = -2;
  } else if (sLen < -2) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
                      RSA_R_SLEN_CHECK_FAILED);
    goto err;
  }

  if (BN_is_zero(rsa->n)) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
                      RSA_R_EMPTY_PUBLIC_KEY);
    goto err;
  }

  MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
  emLen = RSA_size(rsa);
  if (MSBits == 0) {
    assert(emLen >= 1);
    *EM++ = 0;
    emLen--;
  }
  if (sLen == -2) {
    if (emLen < hLen + 2) {
      OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
                        RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
      goto err;
    }
    sLen = emLen - hLen - 2;
  } else if (emLen < hLen + sLen + 2) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
                      RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
    goto err;
  }
  if (sLen > 0) {
    salt = OPENSSL_malloc(sLen);
    if (!salt) {
      OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
                        ERR_R_MALLOC_FAILURE);
      goto err;
    }
    if (!RAND_bytes(salt, sLen)) {
      goto err;
    }
  }
  maskedDBLen = emLen - hLen - 1;
  H = EM + maskedDBLen;
  EVP_MD_CTX_init(&ctx);
  if (!EVP_DigestInit_ex(&ctx, Hash, NULL) ||
      !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) ||
      !EVP_DigestUpdate(&ctx, mHash, hLen)) {
    goto err;
  }
  if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen)) {
    goto err;
  }
  if (!EVP_DigestFinal_ex(&ctx, H, NULL)) {
    goto err;
  }
  EVP_MD_CTX_cleanup(&ctx);

  /* Generate dbMask in place then perform XOR on it */
  if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) {
    goto err;
  }

  p = EM;

  /* Initial PS XORs with all zeroes which is a NOP so just update
   * pointer. Note from a test above this value is guaranteed to
   * be non-negative. */
  p += emLen - sLen - hLen - 2;
  *p++ ^= 0x1;
  if (sLen > 0) {
    for (i = 0; i < sLen; i++) {
      *p++ ^= salt[i];
    }
  }
  if (MSBits) {
    EM[0] &= 0xFF >> (8 - MSBits);
  }

  /* H is already in place so just set final 0xbc */

  EM[emLen - 1] = 0xbc;

  ret = 1;

err:
  OPENSSL_free(salt);

  return ret;
}
Пример #27
0
/*
    Open the SSL module
 */
PUBLIC int sslOpen()
{
    RandBuf     randBuf;
    X509_STORE  *store;
    uchar       resume[16];
    char        *ciphers;

    trace(7, "Initializing SSL");

    randBuf.now = time(0);
    randBuf.pid = getpid();
    RAND_seed((void*) &randBuf, sizeof(randBuf));
#if ME_UNIX_LIKE
    trace(6, "OpenSsl: Before calling RAND_load_file");
    RAND_load_file("/dev/urandom", 256);
    trace(6, "OpenSsl: After calling RAND_load_file");
#endif

    CRYPTO_malloc_init();
#if !ME_WIN_LIKE
    OpenSSL_add_all_algorithms();
#endif
    SSL_library_init();
    SSL_load_error_strings();
    SSLeay_add_ssl_algorithms();

    if ((sslctx = SSL_CTX_new(SSLv23_server_method())) == 0) {
        error("Unable to create SSL context");
        return -1;
    }

    /*
          Set the server certificate and key files
     */
    if (*ME_GOAHEAD_SSL_KEY && sslSetKeyFile(ME_GOAHEAD_SSL_KEY) < 0) {
        sslClose();
        return -1;
    }
    if (*ME_GOAHEAD_SSL_CERTIFICATE && sslSetCertFile(ME_GOAHEAD_SSL_CERTIFICATE) < 0) {
        sslClose();
        return -1;
    }

    if (ME_GOAHEAD_SSL_VERIFY_PEER) {
        SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verifyClientCertificate);
        SSL_CTX_set_verify_depth(sslctx, VERIFY_DEPTH);
    } else {
        SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, verifyClientCertificate);
    }
    /*
          Set the client certificate verification locations
     */
    if (ME_GOAHEAD_SSL_AUTHORITY && *ME_GOAHEAD_SSL_AUTHORITY) {
        if ((!SSL_CTX_load_verify_locations(sslctx, ME_GOAHEAD_SSL_AUTHORITY, NULL)) ||
                (!SSL_CTX_set_default_verify_paths(sslctx))) {
            error("Unable to read cert verification locations");
            sslClose();
            return -1;
        }
        /*
            Define the list of CA certificates to send to the client before they send their client
            certificate for validation
         */
        SSL_CTX_set_client_CA_list(sslctx, SSL_load_client_CA_file(ME_GOAHEAD_SSL_AUTHORITY));
    }
    if (ME_GOAHEAD_SSL_REVOKE && *ME_GOAHEAD_SSL_REVOKE) {
        store = SSL_CTX_get_cert_store(sslctx);
        if (!X509_STORE_load_locations(store, ME_GOAHEAD_SSL_REVOKE, 0)) {
            error("Cannot load certificate revoke list: %s", ME_GOAHEAD_SSL_REVOKE);
            sslClose();
            return -1;
        }
    }

    /*
        Configure DH parameters
     */
    dhKey = getDhKey();
    SSL_CTX_set_tmp_dh_callback(sslctx, dhcallback);

    /*
        Configure cipher suite
     */
    if (ME_GOAHEAD_SSL_CIPHERS && *ME_GOAHEAD_SSL_CIPHERS) {
        ciphers = ME_GOAHEAD_SSL_CIPHERS;
    } else {
        ciphers = OPENSSL_DEFAULT_CIPHERS;
    }
    ciphers = mapCipherNames(ciphers);
    trace(5, "Using OpenSSL ciphers: %s", ciphers);
    if (SSL_CTX_set_cipher_list(sslctx, ciphers) != 1) {
        error("Unable to set cipher list \"%s\"", ciphers);
        sslClose();
        wfree(ciphers);
        return -1;
    }
    wfree(ciphers);

    /*
        Define default OpenSSL options
     */
    SSL_CTX_set_options(sslctx, SSL_OP_ALL);

    /*
        Ensure we generate a new private key for each connection
     */
    SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);

    /*
        Define a session reuse context
     */
    RAND_bytes(resume, sizeof(resume));
    SSL_CTX_set_session_id_context(sslctx, resume, sizeof(resume));

    /*
        Elliptic Curve initialization
     */
#if SSL_OP_SINGLE_ECDH_USE
#ifdef SSL_CTX_set_ecdh_auto
    SSL_CTX_set_ecdh_auto(sslctx, 1);
#else
    {
        EC_KEY  *ecdh;
        cchar   *name;
        int      nid;

        name = ME_GOAHEAD_SSL_CURVE;
        if ((nid = OBJ_sn2nid(name)) == 0) {
            error("Unknown curve name \"%s\"", name);
            sslClose();
            return -1;
        }
        if ((ecdh = EC_KEY_new_by_curve_name(nid)) == 0) {
            error("Unable to create curve \"%s\"", name);
            sslClose();
            return -1;
        }
        SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_ECDH_USE);
        SSL_CTX_set_tmp_ecdh(sslctx, ecdh);
        EC_KEY_free(ecdh);
    }
#endif
#endif

    SSL_CTX_set_mode(sslctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
    SSL_CTX_set_options(sslctx, SSL_OP_MSIE_SSLV2_RSA_PADDING);
#endif
#ifdef SSL_MODE_RELEASE_BUFFERS
    SSL_CTX_set_mode(sslctx, SSL_MODE_RELEASE_BUFFERS);
#endif
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
    SSL_CTX_set_mode(sslctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
#endif

    /*
        Select the required protocols
        Disable both SSLv2 and SSLv3 by default - they are insecure
     */
    SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2);
    SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv3);

#if defined(SSL_OP_NO_TLSv1) && ME_GOAHEAD_SSL_NO_V1
    SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1);
#endif
#if defined(SSL_OP_NO_TLSv1_1) && ME_GOAHEAD_SSL_NO_V1_1
    SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_1);
#endif
#if defined(SSL_OP_NO_TLSv1_2) && ME_GOAHEAD_SSL_NO_V1_2
    SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_2);
#endif


#if defined(SSL_OP_NO_TICKET)
    /*
        Ticket based session reuse is enabled by default
     */
#if defined(ME_GOAHEAD_SSL_TICKET)
    if (ME_GOAHEAD_SSL_TICKET) {
        SSL_CTX_clear_options(sslctx, SSL_OP_NO_TICKET);
    } else {
        SSL_CTX_set_options(sslctx, SSL_OP_NO_TICKET);
    }
#else
    SSL_CTX_clear_options(sslctx, SSL_OP_NO_TICKET);
#endif
#endif

#if defined(SSL_OP_NO_COMPRESSION)
    /*
        CRIME attack targets compression
     */
    SSL_CTX_clear_options(sslctx, SSL_OP_NO_COMPRESSION);
#endif

#if defined(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
    /*
        Disables a countermeasure against a SSL 3.0/TLS 1.0 protocol vulnerability affecting CBC ciphers.
        Defaults to true.
     */
#if defined(ME_GOAHEAD_SSL_EMPTY_FRAGMENTS)
    if (ME_GOAHEAD_SSL_EMPTY_FRAGMENTS) {
        /* SSL_OP_ALL disables empty fragments. Only needed for ancient browsers like IE-6 on SSL-3.0/TLS-1.0 */
        SSL_CTX_clear_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
    } else {
        SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
    }
#else
    SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
#endif
#endif

#if defined(ME_GOAHEAD_SSL_CACHE)
    /*
        Set the number of sessions supported. Default in OpenSSL is 20K.
     */
    SSL_CTX_sess_set_cache_size(sslctx, ME_GOAHEAD_SSL_CACHE);
#else
    SSL_CTX_sess_set_cache_size(sslctx, 256);
#endif

    return 0;
}
Пример #28
0
static int
ltm_rsa_public_encrypt(int flen, const unsigned char* from,
			unsigned char* to, RSA* rsa, int padding)
{
    unsigned char *p, *p0;
    int res;
    size_t size, padlen;
    mp_int enc, dec, n, e;

    if (padding != RSA_PKCS1_PADDING)
	return -1;

    mp_init_multi(&n, &e, &enc, &dec, NULL);

    size = RSA_size(rsa);

    if (size < RSA_PKCS1_PADDING_SIZE || size - RSA_PKCS1_PADDING_SIZE < flen) {
	mp_clear_multi(&n, &e, &enc, &dec);
	return -2;
    }

    BN2mpz(&n, rsa->n);
    BN2mpz(&e, rsa->e);

    p = p0 = malloc(size - 1);
    if (p0 == NULL) {
	mp_clear_multi(&e, &n, &enc, &dec, NULL);
	return -3;
    }

    padlen = size - flen - 3;

    *p++ = 2;
    if (RAND_bytes(p, padlen) != 1) {
	mp_clear_multi(&e, &n, &enc, &dec, NULL);
	free(p0);
	return -4;
    }
    while(padlen) {
	if (*p == 0)
	    *p = 1;
	padlen--;
	p++;
    }
    *p++ = 0;
    memcpy(p, from, flen);
    p += flen;
    assert((p - p0) == size - 1);

    mp_read_unsigned_bin(&dec, p0, size - 1);
    free(p0);

    res = mp_exptmod(&dec, &e, &n, &enc);

    mp_clear_multi(&dec, &e, &n, NULL);

    if (res != 0) {
	mp_clear(&enc);
	return -4;
    }

    {
	size_t ssize;
	ssize = mp_unsigned_bin_size(&enc);
	assert(size >= ssize);
	mp_to_unsigned_bin(&enc, to);
	size = ssize;
    }
    mp_clear(&enc);

    return size;
}
Пример #29
0
static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
		pem_password_cb *cb, void *u)
	{
	int outlen = 24, pklen;
	unsigned char *p, *salt = NULL;
	EVP_CIPHER_CTX cctx;
	EVP_CIPHER_CTX_init(&cctx);
	if (enclevel)
		outlen += PVK_SALTLEN;
	pklen = do_i2b(NULL, pk, 0);
	if (pklen < 0)
		return -1;
	outlen += pklen;
	if (!out)
		return outlen;
	if (*out)
		p = *out;
	else
		{
		p = OPENSSL_malloc(outlen);
		if (!p)
			{
			PEMerr(PEM_F_I2B_PVK,ERR_R_MALLOC_FAILURE);
			return -1;
			}
		*out = p;
		}

	write_ledword(&p, MS_PVKMAGIC);
	write_ledword(&p, 0);
	if (pk->type == EVP_PKEY_DSA)
		write_ledword(&p, MS_KEYTYPE_SIGN);
	else
		write_ledword(&p, MS_KEYTYPE_KEYX);
	write_ledword(&p, enclevel ? 1 : 0);
	write_ledword(&p, enclevel ? PVK_SALTLEN: 0);
	write_ledword(&p, pklen);
	if (enclevel)
		{
		if (RAND_bytes(p, PVK_SALTLEN) <= 0)
			goto error;
		salt = p;
		p += PVK_SALTLEN;
		}
	do_i2b(&p, pk, 0);
	if (enclevel == 0)
		return outlen;
	else
		{
		char psbuf[PEM_BUFSIZE];
		unsigned char keybuf[20];
		int enctmplen, inlen;
		if (cb)
			inlen=cb(psbuf,PEM_BUFSIZE,1,u);
		else
			inlen=PEM_def_callback(psbuf,PEM_BUFSIZE,1,u);
		if (inlen <= 0)
			{
			PEMerr(PEM_F_I2B_PVK,PEM_R_BAD_PASSWORD_READ);
			goto error;
			}
		if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
			    (unsigned char *)psbuf, inlen))
			goto error;
		if (enclevel == 1)
			memset(keybuf + 5, 0, 11);
		p = salt + PVK_SALTLEN + 8;
		if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
			goto error;
		OPENSSL_cleanse(keybuf, 20);
		if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8))
			goto error;
		if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen))
			goto error;
		}
	EVP_CIPHER_CTX_cleanup(&cctx);
	return outlen;

	error:
	EVP_CIPHER_CTX_cleanup(&cctx);
	return -1;
	}
Пример #30
0
static krb5_error_code
kcm_ccache_alloc(krb5_context context,
		 const char *name,
		 kcm_ccache *ccache)
{
    kcm_ccache slot = NULL, p;
    krb5_error_code ret;
    int new_slot = 0;

    *ccache = NULL;

    /* First, check for duplicates */
    HEIMDAL_MUTEX_lock(&ccache_mutex);
    ret = 0;
    for (p = ccache_head; p != NULL; p = p->next) {
	if (p->flags & KCM_FLAGS_VALID) {
	    if (strcmp(p->name, name) == 0) {
		ret = KRB5_CC_WRITE;
		break;
	    }
	} else if (slot == NULL)
	    slot = p;
    }

    if (ret)
	goto out;

    /*
     * Create an enpty slot for us.
     */
    if (slot == NULL) {
	slot = (kcm_ccache_data *)malloc(sizeof(*slot));
	if (slot == NULL) {
	    ret = KRB5_CC_NOMEM;
	    goto out;
	}
	slot->next = ccache_head;
	HEIMDAL_MUTEX_init(&slot->mutex);
	new_slot = 1;
    }

    RAND_bytes(slot->uuid, sizeof(slot->uuid));

    slot->name = strdup(name);
    if (slot->name == NULL) {
	ret = KRB5_CC_NOMEM;
	goto out;
    }

    slot->refcnt = 1;
    slot->flags = KCM_FLAGS_VALID;
    slot->mode = S_IRUSR | S_IWUSR;
    slot->uid = -1;
    slot->gid = -1;
    slot->client = NULL;
    slot->server = NULL;
    slot->creds = NULL;
    slot->key.keytab = NULL;
    slot->tkt_life = 0;
    slot->renew_life = 0;

    if (new_slot)
	ccache_head = slot;

    *ccache = slot;

    HEIMDAL_MUTEX_unlock(&ccache_mutex);
    return 0;

out:
    HEIMDAL_MUTEX_unlock(&ccache_mutex);
    if (new_slot && slot != NULL) {
	HEIMDAL_MUTEX_destroy(&slot->mutex);
	free(slot);
    }
    return ret;
}