Пример #1
0
static bool test_ctr_op(const struct encrypt_desc *encrypt_desc,
			const char *description, int encrypt,
			PK11SymKey *sym_key,
			const char *encoded_cb, const char *output_cb,
			const char *input_name, const char *input,
			const char *output_name, const char *output)
{
	const char *op = encrypt ? "encrypt" : "decrypt";

	bool ok = TRUE;
	chunk_t cb = decode_to_chunk("input counter-block: ", encoded_cb);
	chunk_t tmp = decode_to_chunk(input_name, input);
	chunk_t expected_output = decode_to_chunk(output_name, output);
	chunk_t expected_cb = decode_to_chunk("expected counter-block: ", output_cb);

	/* do_crypt modifies the data and IV in place.  */
	encrypt_desc->encrypt_ops->do_crypt(encrypt_desc, tmp.ptr, tmp.len,
					    sym_key, cb.ptr, encrypt);
	if (!verify_chunk(op, expected_output, tmp)) {
		DBG(DBG_CRYPT, DBG_log("test_ctr_op: %s: %s: output does not match", description, op));
		ok = FALSE;
	}
	if (!verify_chunk("counter-block", expected_cb, cb)) {
		DBG(DBG_CRYPT, DBG_log("test_ctr_op: %s: %s: counter-block does not match", description, op));
		ok = FALSE;
	}

	freeanychunk(cb);
	freeanychunk(expected_cb);
	freeanychunk(tmp);
	freeanychunk(expected_output);

	return ok;
}
Пример #2
0
/*
 * Processing FOR KE values.
 */
void
unpack_KE(struct state *st
	  , struct pluto_crypto_req *r
	  , chunk_t *g)
{
    struct pcr_kenonce *kn = &r->pcr_d.kn;

    if (!st->st_sec_in_use)
    {
	st->st_sec_in_use = TRUE;
	freeanychunk(*g);	/* happens in odd error cases */

	clonetochunk(*g, wire_chunk_ptr(kn, &(kn->gi))
		     , kn->gi.len, "saved gi value");
#ifdef HAVE_LIBNSS
	DBG(DBG_CRYPT, DBG_log("saving DH priv (local secret) and pub key into state struc"));
	clonetochunk(st->st_sec_chunk
		     , wire_chunk_ptr(kn, &(kn->secret))
		     , kn->secret.len, "pointer to DH private key (secret)");

	clonetochunk(st->pubk
		     , wire_chunk_ptr(kn, &(kn->pubk))
		     , kn->pubk.len, "pointer to DH public key");
#else
	n_to_mpz(&st->st_sec
		 , wire_chunk_ptr(kn, &(kn->secret))
		 , kn->secret.len);
	clonetochunk(st->st_sec_chunk
		     , wire_chunk_ptr(kn, &(kn->secret))
		     , kn->secret.len, "long term secret");
#endif
    }
}
Пример #3
0
void unpack_nonce(chunk_t *n, const struct pluto_crypto_req *r)
{
	const struct pcr_kenonce *kn = &r->pcr_d.kn;

	freeanychunk(*n);
	clonetochunk(*n, WIRE_CHUNK_PTR(*kn, n),
		     DEFAULT_NONCE_SIZE, "initiator nonce");
}
Пример #4
0
void unpack_nonce(chunk_t *n, struct pluto_crypto_req *r)
{
	struct pcr_kenonce *kn = &r->pcr_d.kn;

	freeanychunk(*n);
	clonetochunk(*n, wire_chunk_ptr(kn, &(kn->n)),
		     DEFAULT_NONCE_SIZE, "initiator nonce");
}
Пример #5
0
/*
 * Turn the raw key into a SECItem and then SymKey.
 *
 * Since slots are referenced counted and ImportSymKey adds a
 * reference, immediate freeing of the local slot is possible.
 *
 * ImportSymKey makes a copy of the key chunk so that can also be
 * released.
 */
PK11SymKey *decode_to_key(CK_MECHANISM_TYPE cipher_mechanism,
			  const char *encoded_key)
{
	chunk_t raw_key = decode_to_chunk("key", encoded_key);
	PK11SymKey *sym_key = chunk_to_symkey(cipher_mechanism, raw_key);
	freeanychunk(raw_key);
	return sym_key;
}
Пример #6
0
static void monte_run(void)
{
	print_chunk("Seed", seed, 0);
	chunk_t MDi_3 = alloc_chunk(seed.len, "MDi_3");
	chunk_t MDi_2 = alloc_chunk(seed.len, "MDi_2");
	chunk_t MDi_1 = alloc_chunk(seed.len, "MDi_1");
	chunk_t Mi = alloc_chunk(3 * seed.len, "Mi");
	for (int j = 0; j < 100; j++) {
		//MD[0] = MD[1] = MD[2] = Seed
		memcpy(MDi_3.ptr, seed.ptr, seed.len);
		memcpy(MDi_2.ptr, seed.ptr, seed.len);
		memcpy(MDi_1.ptr, seed.ptr, seed.len);
		for (int i = 3; i < 1003; i++) {
			// shuffle
			chunk_t tmp = MDi_3;
			MDi_3 = MDi_2;
			MDi_2 = MDi_1;
			MDi_1 = seed;
			seed = tmp;
			// M[i] = MD[i-3] || MD[i-2] || MD[i-1];
			memcpy(Mi.ptr + seed.len * 0, MDi_3.ptr, seed.len);
			memcpy(Mi.ptr + seed.len * 1, MDi_2.ptr, seed.len);
			memcpy(Mi.ptr + seed.len * 2, MDi_1.ptr, seed.len);
			// MDi = SHA(Mi);
			struct hash_context *hash = hash_alg->hash_ops->init(hash_alg,
									     "sha", DBG_CRYPT);
			hash_alg->hash_ops->digest_bytes(hash, "msg", Mi.ptr, Mi.len);
			hash_alg->hash_ops->final_bytes(&hash, seed.ptr, seed.len);
			// printf("%d ", i);
			// print_chunk("MDi", seed, 0);
		}
		print_line("");
		print_number("COUNT", j);
		// MDj = Seed = MD1002;
		// OUTPUT: MDj; (aka seed)
		print_chunk("MD", seed, 0);
	}
	freeanychunk(MDi_3);
	freeanychunk(MDi_2);
	freeanychunk(MDi_1);
	freeanychunk(Mi);
	print_line("");
	exit(0);
}
Пример #7
0
/*
 * Turn the raw key into SymKey.
 */
PK11SymKey *decode_to_key(const struct encrypt_desc *encrypt_desc,
			  const char *encoded_key)
{
	chunk_t raw_key = decode_to_chunk("raw_key", encoded_key);
	PK11SymKey *symkey = symkey_from_chunk("symkey", DBG_CRYPT,
					       &encrypt_desc->common,
					       raw_key);
	freeanychunk(raw_key);
	return symkey;
}
Пример #8
0
static void ppk_recalc_one(PK11SymKey **sk /* updated */, PK11SymKey *ppk_key, const struct prf_desc *prf_desc, const char *name)
{
	PK11SymKey *t = ikev2_prfplus(prf_desc, ppk_key, *sk, prf_desc->prf_key_size);
	release_symkey(__func__, name, sk);
	*sk = t;
	DBG(DBG_PRIVATE, {
		chunk_t chunk_sk = chunk_from_symkey("sk_chunk", *sk);
		DBG_dump_chunk(name, chunk_sk);
		freeanychunk(chunk_sk);
	});
/*
 * builds a pkcs7 enveloped and signed scep request
 */
chunk_t
scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg
, const x509cert_t *enc_cert, int enc_alg
, const x509cert_t *signer_cert, int digest_alg
, const RSA_private_key_t *private_key)
{
    chunk_t envelopedData, attributes, request;

    envelopedData = pkcs7_build_envelopedData(data, enc_cert, enc_alg);

    attributes = asn1_wrap(ASN1_SET, "mmmmm"
		    , pkcs7_contentType_attribute()
		    , pkcs7_messageDigest_attribute(envelopedData
			, digest_alg)
		    , scep_transId_attribute(transID)
		    , scep_messageType_attribute(msg)
		    , scep_senderNonce_attribute());

    request = pkcs7_build_signedData(envelopedData, attributes
		    , signer_cert, digest_alg, private_key);
    freeanychunk(envelopedData);
    freeanychunk(attributes);
    return request;
}
Пример #10
0
/*
 * SKEYSEED = prf(Ni | Nr, g^ir)
 */
PK11SymKey *ikev2_ike_sa_skeyseed(const struct prf_desc *prf_desc,
				  const chunk_t Ni, const chunk_t Nr,
				  PK11SymKey *dh_secret)
{
	/* key = Ni|Nr */
	chunk_t key = concat_chunk_chunk("key = Ni|Nr", Ni, Nr);
	struct crypt_prf *prf = crypt_prf_init_chunk("ike sa SKEYSEED",
						     DBG_CRYPT,
						     prf_desc,
						     "Ni|Nr", key);
	freeanychunk(key);
	/* seed = g^ir */
	crypt_prf_update_symkey("g^ir", prf, dh_secret);
	/* generate */
	return crypt_prf_final(prf);
}
Пример #11
0
static void msg_run(void)
{
	print_number("Len", len);
	/* byte aligned */
	passert(len == (len & -4));
	/* when len==0, msg may contain one byte :-/ */
	passert((len == 0 && msg.len <= 1)
		|| (len == msg.len * BITS_PER_BYTE));
	print_chunk("Msg", msg, 0);
	struct hash_context *hash = hash_alg->hash_ops->init(hash_alg, "sha", DBG_CRYPT);
	/* See above, use LEN, not MSG.LEN */
	hash_alg->hash_ops->digest_bytes(hash, "msg", msg.ptr, len / BITS_PER_BYTE);
	chunk_t bytes = alloc_chunk(l, "bytes");
	hash_alg->hash_ops->final_bytes(&hash, bytes.ptr, bytes.len);
	print_chunk("MD", bytes, 0);
	freeanychunk(bytes);
}
Пример #12
0
/*
 * Process KE values.
 */
void unpack_KE_from_helper(
	struct state *st,
	const struct pluto_crypto_req *r,
	chunk_t *g)
{
	const struct pcr_kenonce *kn = &r->pcr_d.kn;

	/* ??? if st->st_sec_in_use how could we do our job? */
	passert(!st->st_sec_in_use);
	st->st_sec_in_use = TRUE;
	freeanychunk(*g); /* happens in odd error cases */

	clonetochunk(*g, WIRE_CHUNK_PTR(*kn, gi),
		     kn->gi.len, "saved gi value");
	DBG(DBG_CRYPT,
	    DBG_log("saving DH priv (local secret) and pub key into state struct"));
	st->st_sec_nss = kn->secret;
	st->st_pubk_nss = kn->pubk;
}
Пример #13
0
void calc_ke(struct pluto_crypto_req *r)
{
    MP_INT mp_g;
    MP_INT secret;
    chunk_t gi;
    struct pcr_kenonce *kn = &r->pcr_d.kn;
    const struct oakley_group_desc *group;

    group = lookup_group(kn->oakley_group);

    pluto_crypto_allocchunk(&kn->thespace
			    , &kn->secret
			    , LOCALSECRETSIZE);

    get_rnd_bytes(wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);

    n_to_mpz(&secret, wire_chunk_ptr(kn, &(kn->secret)), LOCALSECRETSIZE);

    mpz_init(&mp_g);

    oswcrypto.mod_exp(&mp_g, group->generator, &secret, group->modulus);

    gi = mpz_to_n(&mp_g, group->bytes);

    pluto_crypto_allocchunk(&kn->thespace, &kn->gi, gi.len);

    {
	char *gip = wire_chunk_ptr(kn, &(kn->gi));

	memcpy(gip, gi.ptr, gi.len);
    }

    DBG(DBG_CRYPT,
	DBG_dump("Local DH secret:\n"
		 , wire_chunk_ptr(kn, &(kn->secret))
		 , LOCALSECRETSIZE);
	DBG_dump_chunk("Public DH value sent:\n", gi));

    /* clean up after ourselves */
    mpz_clear(&mp_g);
    mpz_clear(&secret);
    freeanychunk(gi);
}
Пример #14
0
void free_id_content(struct id *id)
{
	switch (id->kind) {
	case ID_FQDN:
	case ID_USER_FQDN:
	case ID_DER_ASN1_DN:
	case ID_KEY_ID:
		freeanychunk(id->name);
		break;
	case ID_MYID:
	case ID_FROMCERT:
	case ID_NONE:
	case ID_IPV4_ADDR:
	case ID_IPV6_ADDR:
		break;
	default:
		bad_case(id->kind);
	}
}
Пример #15
0
static void gcm_run_test(void)
{
	print_number("Count", NULL, count);
	print_symkey("Key", NULL, key, 0);
	print_chunk("IV", NULL, iv, 0);
	print_chunk("CT", NULL, ct, 0);
	print_chunk("AAD", NULL, aad, 0);
	print_chunk("Tag", NULL, tag, 0);
	const struct encrypt_desc *gcm_alg = lookup_by_taglen();
	if (gcm_alg == NULL) {
		fprintf(stderr, "taglen %lu not supported\n",
			taglen);
		return;
	}
	PK11SymKey *gcm_key = encrypt_key_from_symkey_bytes("GCM key", gcm_alg,
							    0, sizeof_symkey(key),
							    key);

	chunk_t text_and_tag = clone_chunk_chunk(ct, tag, "text-and-tag");

	bool result = gcm_alg->encrypt_ops
		->do_aead(gcm_alg,
			  salt.ptr, salt.len,
			  iv.ptr, iv.len,
			  aad.ptr, aad.len,
			  text_and_tag.ptr,
			  ct.len, tag.len,
			  gcm_key,
			  FALSE/*encrypt*/);
	if (result) {
		/* plain text */
		chunk_t pt = {
			.ptr = text_and_tag.ptr,
			.len = ct.len,
		};
		print_chunk("PT", NULL, pt, 0);
	} else {
		print_line("FAIL");
	}
	release_symkey(__func__, "GCM-key", &gcm_key);
	freeanychunk(text_and_tag);
}
Пример #16
0
/*
 * Processing FOR KE values.
 */
void
unpack_KE(struct state *st
	  , struct pluto_crypto_req *r
	  , chunk_t *g)
{
    struct pcr_kenonce *kn = &r->pcr_d.kn;

    if (!st->st_sec_in_use)
    {
	st->st_sec_in_use = TRUE;
	freeanychunk(*g);	/* happens in odd error cases */
	
	clonetochunk(*g, wire_chunk_ptr(kn, &(kn->gi))
		     , kn->gi.len, "saved gi value");

	n_to_mpz(&st->st_sec
		 , wire_chunk_ptr(kn, &(kn->secret))
		 , kn->secret.len);
	clonetochunk(st->st_sec_chunk
		     , wire_chunk_ptr(kn, &(kn->secret))
		     , kn->secret.len, "long term secret");
    }
}
Пример #17
0
stf_status ikev2_calc_no_ppk_auth(struct state *st,
			unsigned char *id_hash,
			chunk_t *no_ppk_auth /* output */)
{
	struct connection *c = st->st_connection;
	enum keyword_authby authby = c->spd.this.authby;

	freeanychunk(*no_ppk_auth);	/* in case it was occupied */

	switch (authby) {
	case AUTH_RSASIG:
	{
		const struct asn1_hash_blob *h = NULL;

		if (st->st_hash_negotiated & NEGOTIATE_AUTH_HASH_SHA2_512) {
			h = &asn1_rsa_pss_sha2_512;
		} else if (st->st_hash_negotiated & NEGOTIATE_AUTH_HASH_SHA2_384) {
			h = &asn1_rsa_pss_sha2_384;
		} else if (st->st_hash_negotiated & NEGOTIATE_AUTH_HASH_SHA2_256) {
			h = &asn1_rsa_pss_sha2_256;
		} else if (c->sighash_policy & POL_SIGHASH_NONE) {
			/* RSA with SHA1 without Digsig: no oid blob appended */
			if (!ikev2_calculate_rsa_hash(st,
					st->st_original_role, id_hash, NULL,
					no_ppk_auth, IKEv2_AUTH_HASH_SHA1))
			{
				/* ??? what diagnostic? */
				return STF_FAIL;
			}
			return STF_OK;
		} else {
			loglog(RC_LOG_SERIOUS, "No compatible hash algo");
			return STF_FAIL;
		}

		chunk_t hashval;

		if (!ikev2_calculate_rsa_hash(st, st->st_original_role,
				id_hash, NULL, &hashval,
				h->hash_algo)) {
			/* ??? what diagnostic? */
			return STF_FAIL;
		}

		if (st->st_seen_hashnotify) {
			/*
			 * combine blobs to create no_ppk_auth:
			 * - ASN.1 algo blob
			 * - hashval
			 */
			int len = h->blob_sz + hashval.len;
			u_char *blobs = alloc_bytes(len,
				"bytes for blobs for AUTH_DIGSIG NO_PPK_AUTH");

			memcpy(&blobs[0], h->blob, h->blob_sz);
			memcpy(&blobs[h->blob_sz], hashval.ptr, hashval.len);
			freeanychunk(hashval);

			setchunk(*no_ppk_auth, blobs, len);
		}
		return STF_OK;
	}
	case AUTH_PSK:
		/* store in no_ppk_auth */
		if (!ikev2_create_psk_auth(AUTH_PSK, st, id_hash, no_ppk_auth)) {
			/* ??? what diagnostic? */
			return STF_INTERNAL_ERROR;
		}
		return STF_OK;

	default:
		bad_case(authby);
	}
}
Пример #18
0
static bool test_gcm_vector(const struct encrypt_desc *encrypt_desc,
			    const struct gcm_test_vector *test)
{
	DBG(DBG_CRYPT, DBG_log("test_gcm_vector: enter"));

	const size_t salt_size = encrypt_desc->salt_size;

	bool ok = TRUE;

	PK11SymKey *sym_key = decode_to_key(encrypt_desc, test->key);

	chunk_t salted_iv = decode_to_chunk("salted IV", test->salted_iv);
	passert(salted_iv.len == encrypt_desc->wire_iv_size + salt_size);
	chunk_t salt = { .ptr = salted_iv.ptr, .len = salt_size };
	chunk_t wire_iv = { .ptr = salted_iv.ptr + salt_size, .len = salted_iv.len - salt_size };

	chunk_t aad = decode_to_chunk("AAD", test->aad);
	chunk_t plaintext = decode_to_chunk("plaintext", test->plaintext);
	chunk_t ciphertext = decode_to_chunk("ciphertext", test->ciphertext);
	passert(plaintext.len == ciphertext.len);
	size_t len = plaintext.len;
	chunk_t tag = decode_to_chunk("tag", test->tag);

	chunk_t text_and_tag;
	text_and_tag.len = len + tag.len;
	text_and_tag.ptr = alloc_bytes(text_and_tag.len, "GCM data");

	/* macro to test encryption or decryption
	 *
	 * This would be better as a function but it uses too many locals
	 * from test_gcm_vector to be pleasant:
	 *	text_and_tag, len, tag, aad, salt, wire_iv, sym_key
	 */
#	define try(enc, desc, from, to) {  \
		memcpy(text_and_tag.ptr, from.ptr, from.len);  \
		text_and_tag.len = len + tag.len;  \
		DBG(DBG_CRYPT,  \
		    DBG_log("test_gcm_vector: %s: aad-size=%zd salt-size=%zd wire-IV-size=%zd text-size=%zd tag-size=%zd",  \
			    desc, aad.len, salt.len, wire_iv.len, len, tag.len);  \
		    DBG_dump_chunk("test_gcm_vector: text+tag on call",  \
				   text_and_tag));  \
		if (!encrypt_desc->encrypt_ops->do_aead(encrypt_desc,  \
							salt.ptr, salt.len, \
							wire_iv.ptr, wire_iv.len, \
							aad.ptr, aad.len, \
							text_and_tag.ptr, \
							len, tag.len,	\
							sym_key, enc) || \
		    !verify_chunk_data("output ciphertext",  \
				   to, text_and_tag.ptr) ||  \
		    !verify_chunk_data("TAG", tag, text_and_tag.ptr + len))  \
			ok = FALSE;  \
		DBG(DBG_CRYPT, DBG_dump_chunk("test_gcm_vector: text+tag on return",  \
					      text_and_tag));  \
	}

	/* test decryption */
	memcpy(text_and_tag.ptr + len, tag.ptr, tag.len);
	try(FALSE, "decrypt", ciphertext, plaintext);

	/* test encryption */
	memset(text_and_tag.ptr + len, '\0', tag.len);
	try(TRUE, "encrypt", plaintext, ciphertext);

#	undef try

	freeanychunk(salted_iv);
	freeanychunk(aad);
	freeanychunk(plaintext);
	freeanychunk(ciphertext);
	freeanychunk(tag);
	freeanychunk(text_and_tag);

	/* Clean up.  */
	release_symkey(__func__, "sym_key", &sym_key);

	DBG(DBG_CRYPT, DBG_log("test_gcm_vector: %s", ok ? "passed" : "failed"));
	return ok;
}

bool test_gcm_vectors(const struct encrypt_desc *encrypt_desc,
		      const struct gcm_test_vector *tests)
{
	bool ok = TRUE;
	const struct gcm_test_vector *test;
	for (test = tests; test->key != NULL; test++) {
		if (!test_gcm_vector(encrypt_desc, test)) {
			ok = FALSE;
		}
	}
	return ok;
}
Пример #19
0
void hmac_init(struct hmac_ctx *ctx,
	       const struct hash_desc *h,
	       const u_char *key, size_t key_len)
{
	ctx->h = h;
	ctx->hmac_digest_len = h->hash_digest_len;

	/* DBG(DBG_CRYPT, DBG_log("NSS: hmac init")); */
	SECStatus status;
	PK11SymKey *symkey = NULL, *tkey1 = NULL;
	/* PK11SymKey *tkey1=NULL; */
	unsigned int klen;
	chunk_t hmac_opad, hmac_ipad, hmac_pad;

	memcpy(&symkey, key, key_len);
	klen =  PK11_GetKeyLength(symkey);

	hmac_opad = hmac_pads(HMAC_OPAD, h->hash_block_size);
	hmac_ipad = hmac_pads(HMAC_IPAD, h->hash_block_size);
	hmac_pad  = hmac_pads(0x00, h->hash_block_size - klen);

	if (klen > h->hash_block_size) {
		tkey1 = PK11_Derive_lsw(symkey, nss_key_derivation_mech(
						h),
					NULL, CKM_CONCATENATE_BASE_AND_DATA, CKA_DERIVE,
					0);
	} else {
		tkey1 = symkey;
	}

	PK11SymKey *tkey2 = pk11_derive_wrapper_lsw(tkey1,
						    CKM_CONCATENATE_BASE_AND_DATA,
						    hmac_pad, CKM_XOR_BASE_AND_DATA, CKA_DERIVE,
						    h->hash_block_size);

	PR_ASSERT(tkey2 != NULL);
	ctx->ikey = pk11_derive_wrapper_lsw(tkey2, CKM_XOR_BASE_AND_DATA,
					    hmac_ipad, nss_hash_mech(
						    h), CKA_DIGEST, 0);

	PR_ASSERT(ctx->ikey != NULL);
	ctx->okey = pk11_derive_wrapper_lsw(tkey2, CKM_XOR_BASE_AND_DATA,
					    hmac_opad, nss_hash_mech(
						    h), CKA_DIGEST, 0);

	PR_ASSERT(ctx->okey != NULL);

	if (tkey1 != symkey)
		PK11_FreeSymKey(tkey1);
	PK11_FreeSymKey(tkey2);

	freeanychunk(hmac_opad);
	freeanychunk(hmac_ipad);
	freeanychunk(hmac_pad);
	ctx->ctx_nss = PK11_CreateDigestContext(nss_hash_oid(h));
	PR_ASSERT(ctx->ctx_nss != NULL);

	status = PK11_DigestBegin(ctx->ctx_nss);
	PR_ASSERT(status == SECSuccess);

	status = PK11_DigestKey(ctx->ctx_nss, ctx->ikey);
	PR_ASSERT(status == SECSuccess);

}
Пример #20
0
int main(int argc, char *argv[])
{
    bool  recalculate = FALSE;
    int   len;
    err_t e;
    err_t err = NULL;
    char *infile;
    char *conn_name;
    int  lineno=0;
    struct connection *c1 = NULL;
    struct id moon, cassidy;
    struct adns_continuation *cr1 = NULL;

#ifdef HAVE_EFENCE
    EF_PROTECT_FREE=1;
#endif

    initproctitle(argc, argv);
    progname = argv[0];
    leak_detective = 1;

    if(argc != 3 && argc!=4) {
	fprintf(stderr, "Usage: %s [-r] <whackrecord> <conn-name>\n", progname);
	exit(10);
    }
    /* skip argv0 */
    argc--; argv++;

    if(strcmp(argv[0], "-r")==0) {
        recalculate = 1;    /* do all crypto */
        argc--; argv++;
    }

    tool_init_log();
    cur_debugging |= DBG_DNS;
    init_adns();

    {
    	int r;
	struct sigaction act;

	act.sa_handler = &childhandler;
	act.sa_flags   = SA_RESTART;
	r = sigaction(SIGCHLD, &act, NULL);
	passert(r == 0);
    }

    reset_globals();

    /* setup a query */
    cr1 = alloc_thing(struct adns_continuation, "moon lookup");
    moon.kind = ID_FQDN;
    strtochunk(moon.name, "moon.testing.openswan.org", "dns name");
    e = start_adns_query(&moon, NULL, ns_t_key,
                         moon_continue, cr1);
    freeanychunk(moon.name);
    process_dns_results();

#if 0
    cr1 = alloc_thing(struct adns_continuation, "cassidy lookup");
    cassidy.kind = ID_FQDN;
    strtochunk(cassidy.name, "cassidy.sandelman.ca", "dns name 2");
    e = start_adns_query(&cassidy, NULL, ns_t_key,
                         cassidy_continue, cr1);
    freeanychunk(cassidy.name);
    process_dns_results();
#endif

    /* re-use cassidy */
    cr1 = alloc_thing(struct adns_continuation, "cassidy A lookup");
    e = start_adns_hostname(AF_UNSPEC, "cassidy.sandelman.ca", cassidy_host_continue, cr1);
    process_dns_results();

    stop_adns();
    report_leaks();

    tool_close_log();
    exit(0);
}
Пример #21
0
struct private_key_stuff *lsw_nss_foreach_private_key_stuff(secret_eval func,
							    void *uservoid,
							    lsw_nss_buf_t err)
{
	/*
	 * So test for error with "if (err[0]) ..." works.
	 */
	err[0] = '\0';

	PK11SlotInfo *slot = lsw_nss_get_authenticated_slot(err);
	if (slot == NULL) {
		return NULL;
	}

	SECKEYPrivateKeyList *list = PK11_ListPrivateKeysInSlot(slot);
	if (list == NULL) {
		snprintf(err, sizeof(lsw_nss_buf_t), "no list");
		PK11_FreeSlot(slot);
		return NULL;
	}

	int line = 1;

	struct private_key_stuff *result = NULL;

	SECKEYPrivateKeyListNode *node;
	for (node = PRIVKEY_LIST_HEAD(list);
             !PRIVKEY_LIST_END(node, list);
	     node = PRIVKEY_LIST_NEXT(node)) {

		if (SECKEY_GetPrivateKeyType(node->key) != rsaKey) {
			/* only rsa for now */
			continue;
		}

		struct private_key_stuff pks = {
			.kind = PPK_RSA,
			.on_heap = TRUE,
		};

		{
			SECItem *nss_ckaid
				= PK11_GetLowLevelKeyIDForPrivateKey(node->key);
			if (nss_ckaid == NULL) {
				// fprintf(stderr, "ckaid not found\n");
				continue;
			}
			const char *err = form_ckaid_nss(nss_ckaid,
							 &pks.u.RSA_private_key.pub.ckaid);
			SECITEM_FreeItem(nss_ckaid, PR_TRUE);
			if (err) {
				// fprintf(stderr, "ckaid not found\n");
				continue;
			}
		}

		{
			SECKEYPublicKey *pubkey = SECKEY_ConvertToPublicKey(node->key);
			if (pubkey != NULL) {
				fill_RSA_public_key(&pks.u.RSA_private_key.pub, pubkey);
				SECKEY_DestroyPublicKey(pubkey);
			}
		}

		/*
		 * Only count private keys that get processed.
		 */
		pks.line = line++;

		int ret = func(NULL, &pks, uservoid);
		if (ret == 0) {
			/*
			 * save/return the result.
			 *
			 * XXX: Potential Memory leak.
			 *
			 * lsw_foreach_secret() + lsw_get_pks()
			 * returns an object that must not be freed
			 * BUT lsw_nss_foreach_private_key_stuff()
			 * returns an object that must be freed.
			 *
			 * For moment ignore this - as only caller is
			 * showhostkey.c which quickly exits.
			 */
			result = clone_thing(pks, "pks");
			break;
		}

		freeanyckaid(&pks.u.RSA_private_key.pub.ckaid);
		freeanychunk(pks.u.RSA_private_key.pub.e);
		freeanychunk(pks.u.RSA_private_key.pub.n);

		if (ret < 0) {
			break;
		}
	}

	SECKEY_DestroyPrivateKeyList(list);
	PK11_FreeSlot(slot);

	return result;
}
Пример #22
0
/* MUST BE THREAD-SAFE */
static PK11SymKey *calc_dh_shared(const chunk_t g,	/* converted to SECItem */
				  /*const*/ SECKEYPrivateKey *privk,	/* NSS doesn't do const */
				  const struct oakley_group_desc *group,
				  const SECKEYPublicKey *local_pubk)
{
	struct timeval tv0;
	SECKEYPublicKey *remote_pubk;
	SECItem nss_g;
	PK11SymKey *dhshared;
	PRArenaPool *arena;
	SECStatus status;
	unsigned int dhshared_len;

	DBG(DBG_CRYPT,
		DBG_log("Started DH shared-secret computation in NSS:"));

	gettimeofday(&tv0, NULL);

	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
	passert(arena != NULL);

	remote_pubk = (SECKEYPublicKey *)
		PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));

	remote_pubk->arena = arena;
	remote_pubk->keyType = dhKey;
	remote_pubk->pkcs11Slot = NULL;
	remote_pubk->pkcs11ID = CK_INVALID_HANDLE;

	nss_g.data = g.ptr;
	nss_g.len = (unsigned int)g.len;
	nss_g.type = siBuffer;

	status = SECITEM_CopyItem(remote_pubk->arena, &remote_pubk->u.dh.prime,
				  &local_pubk->u.dh.prime);
	passert(status == SECSuccess);

	status = SECITEM_CopyItem(remote_pubk->arena, &remote_pubk->u.dh.base,
				  &local_pubk->u.dh.base);
	passert(status == SECSuccess);

	status = SECITEM_CopyItem(remote_pubk->arena,
				  &remote_pubk->u.dh.publicValue, &nss_g);
	passert(status == SECSuccess);

	dhshared = PK11_PubDerive(privk, remote_pubk, PR_FALSE, NULL, NULL,
				  CKM_DH_PKCS_DERIVE,
				  CKM_CONCATENATE_DATA_AND_BASE,
				  CKA_DERIVE, group->bytes,
				  lsw_return_nss_password_file_info());
	passert(dhshared != NULL);

	dhshared_len = PK11_GetKeyLength(dhshared);
	if (group->bytes > dhshared_len) {
		DBG(DBG_CRYPT,
		    DBG_log("Dropped %lu leading zeros",
			    group->bytes - dhshared_len));
		chunk_t zeros;
		PK11SymKey *newdhshared;
		CK_KEY_DERIVATION_STRING_DATA string_params;
		SECItem params;

		zeros = hmac_pads(0x00, group->bytes - dhshared_len);
		params.data = (unsigned char *)&string_params;
		params.len = sizeof(string_params);
		string_params.pData = zeros.ptr;
		string_params.ulLen = zeros.len;

		newdhshared = PK11_Derive(dhshared,
					  CKM_CONCATENATE_DATA_AND_BASE,
					  &params,
					  CKM_CONCATENATE_DATA_AND_BASE,
					  CKA_DERIVE, 0);
		passert(newdhshared != NULL);
		PK11_FreeSymKey(dhshared);
		dhshared = newdhshared;
		freeanychunk(zeros);
	} else {
		DBG(DBG_CRYPT,
		    DBG_log("Dropped no leading zeros %d", dhshared_len));
	}

	/* nss_symkey_log(dhshared, "dhshared"); */

	DBG(DBG_CRYPT, {
		struct timeval tv1;
		unsigned long tv_diff;

		gettimeofday(&tv1, NULL);
		tv_diff = (tv1.tv_sec  - tv0.tv_sec) * 1000000 +
			  (tv1.tv_usec - tv0.tv_usec);
		DBG_log("calc_dh_shared(): time elapsed (%s): %ld usec",
			       enum_show(&oakley_group_names, group->group),
			       tv_diff);
	});
Пример #23
0
void
hmac_init(struct hmac_ctx *ctx,
    const struct hash_desc *h,
    const u_char *key, size_t key_len)
{
#ifndef HAVE_LIBNSS
    int k;
#endif
    ctx->h = h;
    ctx->hmac_digest_len = h->hash_digest_len;

#ifdef HAVE_LIBNSS
    /* DBG(DBG_CRYPT, DBG_log("NSS: hmac init")); */
    SECStatus status;
    PK11SymKey *symkey=NULL, *tkey1=NULL;
    /* PK11SymKey *tkey1=NULL; */
    unsigned int klen;
    chunk_t hmac_opad, hmac_ipad, hmac_pad;

    memcpy(&symkey, key, key_len);
    klen =  PK11_GetKeyLength(symkey);

    hmac_opad = hmac_pads(HMAC_OPAD,HMAC_BUFSIZE);
    hmac_ipad = hmac_pads(HMAC_IPAD,HMAC_BUFSIZE);
    hmac_pad  = hmac_pads(0x00,HMAC_BUFSIZE-klen);

    if(klen > HMAC_BUFSIZE)
    {
	tkey1 = PK11_Derive_osw(symkey, nss_key_derivation_mech(h)
				, NULL, CKM_CONCATENATE_BASE_AND_DATA, CKA_DERIVE, 0);
    }
    else
    {
	tkey1 = symkey;
    }

    PK11SymKey *tkey2 = pk11_derive_wrapper_osw(tkey1, CKM_CONCATENATE_BASE_AND_DATA
				, hmac_pad,CKM_XOR_BASE_AND_DATA, CKA_DERIVE, HMAC_BUFSIZE);

    PR_ASSERT(tkey2!=NULL);
    ctx->ikey = pk11_derive_wrapper_osw(tkey2, CKM_XOR_BASE_AND_DATA
					, hmac_ipad,nss_hash_mech(h), CKA_DIGEST, 0);

    PR_ASSERT(ctx->ikey !=NULL);
    ctx->okey = pk11_derive_wrapper_osw(tkey2, CKM_XOR_BASE_AND_DATA
					, hmac_opad,nss_hash_mech(h), CKA_DIGEST, 0);

    PR_ASSERT(ctx->okey !=NULL);

    if(tkey1!=symkey) {
	PK11_FreeSymKey(tkey1);
    }
    PK11_FreeSymKey(tkey2);

    freeanychunk(hmac_opad);
    freeanychunk(hmac_ipad);
    freeanychunk(hmac_pad);
    ctx->ctx_nss = PK11_CreateDigestContext(nss_hash_oid(h));
    PR_ASSERT(ctx->ctx_nss!=NULL);

    status=PK11_DigestBegin(ctx->ctx_nss);
    PR_ASSERT(status==SECSuccess);

    status=PK11_DigestKey(ctx->ctx_nss, ctx->ikey);
    PR_ASSERT(status==SECSuccess);

#else

    /* Prepare the two pads for the HMAC */

    memset(ctx->buf1, '\0', HMAC_BUFSIZE);

    if (key_len <= HMAC_BUFSIZE)
    {
	memcpy(ctx->buf1, key, key_len);
    }
    else
    {
	h->hash_init(&ctx->hash_ctx);
	h->hash_update(&ctx->hash_ctx, key, key_len);
	h->hash_final(ctx->buf1, &ctx->hash_ctx);
    }

    memcpy(ctx->buf2, ctx->buf1, HMAC_BUFSIZE);

    for (k = 0; k < HMAC_BUFSIZE; k++)
    {
	ctx->buf1[k] ^= HMAC_IPAD;
	ctx->buf2[k] ^= HMAC_OPAD;
    }

    hmac_reinit(ctx);
#endif
}
Пример #24
0
static bool ike_alg_nss_gcm(const struct encrypt_desc *alg,
			    u_int8_t *salt, size_t salt_size,
			    u_int8_t *wire_iv, size_t wire_iv_size,
			    u_int8_t *aad, size_t aad_size,
			    u_int8_t *text_and_tag,
			    size_t text_size, size_t tag_size,
			    PK11SymKey *sym_key, bool enc)
{
	/* See pk11gcmtest.c */
	bool ok = TRUE;

	chunk_t salt_chunk = {
		.ptr = salt,
		.len = salt_size,
	};
	chunk_t wire_iv_chunk = {
		.ptr = wire_iv,
		.len = wire_iv_size,
	};
	chunk_t iv = concat_chunk_chunk("IV", salt_chunk, wire_iv_chunk);

	CK_GCM_PARAMS gcm_params;
	gcm_params.pIv = iv.ptr;
	gcm_params.ulIvLen = iv.len;
	gcm_params.pAAD = aad;
	gcm_params.ulAADLen = aad_size;
	gcm_params.ulTagBits = tag_size * 8;

	SECItem param;
	param.type = siBuffer;
	param.data = (void*)&gcm_params;
	param.len = sizeof gcm_params;

	/* Output buffer for transformed data.  */
	size_t text_and_tag_size = text_size + tag_size;
	u_int8_t *out_buf = PR_Malloc(text_and_tag_size);
	unsigned int out_len = 0;

	if (enc) {
		SECStatus rv = PK11_Encrypt(sym_key, alg->common.nss_mechanism,
					    &param, out_buf, &out_len,
					    text_and_tag_size,
					    text_and_tag, text_size);
		if (rv != SECSuccess) {
			loglog(RC_LOG_SERIOUS,
			       "do_aes_gcm: PK11_Encrypt failure (err %d)", PR_GetError());
			ok = FALSE;
		} else if (out_len != text_and_tag_size) {
			loglog(RC_LOG_SERIOUS,
			       "do_aes_gcm: PK11_Encrypt output length of %u not the expected %zd",
			       out_len, text_and_tag_size);
			ok = FALSE;
		}
	} else {
		SECStatus rv = PK11_Decrypt(sym_key, CKM_AES_GCM, &param,
					    out_buf, &out_len, text_and_tag_size,
					    text_and_tag, text_and_tag_size);
		if (rv != SECSuccess) {
			loglog(RC_LOG_SERIOUS,
			       "do_aes_gcm: PK11_Decrypt failure (err %d)", PR_GetError());
			ok = FALSE;
		} else if (out_len != text_size) {
			loglog(RC_LOG_SERIOUS,
			       "do_aes_gcm: PK11_Decrypt output length of %u not the expected %zd",
			       out_len, text_size);
			ok = FALSE;
		}
	}

	memcpy(text_and_tag, out_buf, out_len);
	PR_Free(out_buf);
	freeanychunk(iv);

	return ok;
}
Пример #25
0
/* here we are just freeing RAM */
void free_state(struct state *st)
{
    delete_event(st);	/* delete any pending timer event */

    {
	struct msgid_list *p = st->st_used_msgids;

	while (p != NULL)
	{
	    struct msgid_list *q = p;
	    p = p->next;
	    pfree(q);
	}
    }

    unreference_key(&st->st_peer_pubkey);

    free_sa(st->st_sadb);
    st->st_sadb=NULL;

    if (st->st_sec_in_use) {
#ifdef HAVE_LIBNSS
	SECKEYPrivateKey *privk;
	SECKEYPublicKey   *pubk;
	memcpy(&pubk,st->pubk.ptr,st->pubk.len);
	SECKEY_DestroyPublicKey(pubk);
	freeanychunk(st->pubk);
	memcpy(&privk,st->st_sec_chunk.ptr,st->st_sec_chunk.len);
	SECKEY_DestroyPrivateKey(privk);
#else
	mpz_clear(&(st->st_sec));
#endif
	pfreeany(st->st_sec_chunk.ptr);
    }

    freeanychunk(st->st_firstpacket_me);
    freeanychunk(st->st_firstpacket_him);
    freeanychunk(st->st_tpacket);
    freeanychunk(st->st_rpacket);
    freeanychunk(st->st_p1isa);
    freeanychunk(st->st_gi);
    freeanychunk(st->st_gr);
    freeanychunk(st->st_shared);
    freeanychunk(st->st_ni);
    freeanychunk(st->st_nr);
#ifdef HAVE_LIBNSS
    free_osw_nss_symkey(st->st_skeyid);
    free_osw_nss_symkey(st->st_skey_d);
    free_osw_nss_symkey(st->st_skey_ai);
    free_osw_nss_symkey(st->st_skey_ar);
    free_osw_nss_symkey(st->st_skey_ei);
    free_osw_nss_symkey(st->st_skey_er);
    free_osw_nss_symkey(st->st_skey_pi);
    free_osw_nss_symkey(st->st_skey_pr);
    free_osw_nss_symkey(st->st_enc_key);

    if(st->st_ah.our_keymat!=NULL)
    memset(st->st_ah.our_keymat, 0, st->st_ah.keymat_len);

    if(st->st_ah.peer_keymat!=NULL)
    memset(st->st_ah.peer_keymat, 0, st->st_ah.keymat_len);

    if(st->st_esp.our_keymat!=NULL)
    memset(st->st_esp.our_keymat, 0, st->st_esp.keymat_len);

    if(st->st_esp.peer_keymat!=NULL)
    memset(st->st_esp.peer_keymat, 0, st->st_esp.keymat_len);
#endif
    freeanychunk(st->st_skeyid);
    freeanychunk(st->st_skey_d);
    freeanychunk(st->st_skey_ai);
    freeanychunk(st->st_skey_ar);
    freeanychunk(st->st_skey_ei);
    freeanychunk(st->st_skey_er);
    freeanychunk(st->st_skey_pi);
    freeanychunk(st->st_skey_pr);
    freeanychunk(st->st_enc_key);
    pfreeany(st->st_ah.our_keymat);
    pfreeany(st->st_ah.peer_keymat);
    pfreeany(st->st_esp.our_keymat);
    pfreeany(st->st_esp.peer_keymat);
    freeanychunk(st->st_xauth_password);
#ifdef HAVE_LABELED_IPSEC
    pfreeany(st->sec_ctx);
#endif
    pfree(st);
}
Пример #26
0
void calc_ke(struct pluto_crypto_req *r)
{
    chunk_t  prime;
    chunk_t  base;
    SECKEYDHParams      dhp;
    PK11SlotInfo *slot = NULL;
    SECKEYPrivateKey *privk;
    SECKEYPublicKey   *pubk;
    struct pcr_kenonce *kn = &r->pcr_d.kn;
    const struct oakley_group_desc *group;

    group = lookup_group(kn->oakley_group);


    base  = mpz_to_n2(group->generator);
    prime = mpz_to_n2(group->modulus);

    DBG(DBG_CRYPT,DBG_dump_chunk("NSS: Value of Prime:\n", prime));
    DBG(DBG_CRYPT,DBG_dump_chunk("NSS: Value of base:\n", base));

    dhp.prime.data=prime.ptr;
    dhp.prime.len=prime.len;
    dhp.base.data=base.ptr;
    dhp.base.len=base.len;

    slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN,osw_return_nss_password_file_info());
    if(!slot) {
	loglog(RC_LOG_SERIOUS, "NSS: slot for DH key gen is NULL");
    }
    PR_ASSERT(slot!=NULL);

    while(1) {
	privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, &dhp, &pubk, PR_FALSE, PR_TRUE, osw_return_nss_password_file_info());
	if(!privk) {
	   loglog(RC_LOG_SERIOUS, "NSS: DH private key creation failed (err %d)", PR_GetError());
	}
	PR_ASSERT(privk!=NULL);

	if( group-> bytes == pubk->u.dh.publicValue.len ) {
	   DBG(DBG_CRYPT, DBG_log("NSS: generated dh priv and pub keys: %d\n", pubk->u.dh.publicValue.len));
	   break;
	} else {
	   DBG(DBG_CRYPT, DBG_log("NSS: generating dh priv and pub keys"));
	   if (privk) SECKEY_DestroyPrivateKey(privk);
	   if (pubk)  SECKEY_DestroyPublicKey(pubk);
	   }
    }

    pluto_crypto_allocchunk(&kn->thespace, &kn->secret, sizeof(SECKEYPrivateKey*));
    {
	char *gip = wire_chunk_ptr(kn, &(kn->secret));
	memcpy(gip, &privk, sizeof(SECKEYPrivateKey *));
    }

    pluto_crypto_allocchunk(&kn->thespace, &kn->gi, pubk->u.dh.publicValue.len);
    {
	char *gip = wire_chunk_ptr(kn, &(kn->gi));
	memcpy(gip, pubk->u.dh.publicValue.data, pubk->u.dh.publicValue.len);
    }

    pluto_crypto_allocchunk(&kn->thespace, &kn->pubk, sizeof(SECKEYPublicKey*));
    {
	char *gip = wire_chunk_ptr(kn, &(kn->pubk));
	memcpy(gip, &pubk, sizeof(SECKEYPublicKey*));
    }

    DBG(DBG_CRYPT,
       DBG_dump("NSS: Local DH secret:\n"
                , wire_chunk_ptr(kn, &(kn->secret))
                , sizeof(SECKEYPrivateKey*));
       DBG_dump("NSS: Public DH value sent(computed in NSS):\n", wire_chunk_ptr(kn, &(kn->gi)),pubk->u.dh.publicValue.len));

    DBG(DBG_CRYPT,
        DBG_dump("NSS: Local DH public value (pointer):\n"
                 , wire_chunk_ptr(kn, &(kn->pubk))
                 , sizeof(SECKEYPublicKey*)));

    /* clean up after ourselves */
    if (slot) {
	PK11_FreeSlot(slot);
    }
    /* if (privk){SECKEY_DestroyPrivateKey(privk);} */
    /* if (pubk){SECKEY_DestroyPublicKey(pubk);} */
    freeanychunk(prime);
    freeanychunk(base);
}