コード例 #1
0
ファイル: rsapub.c プロジェクト: mcr/Openswan
/* decode of RSA pubkey chunk
 * - format specified in RFC 2537 RSA/MD5 Keys and SIGs in the DNS
 * - exponent length in bytes (1 or 3 octets)
 *   + 1 byte if in [1, 255]
 *   + otherwise 0x00 followed by 2 bytes of length
 * - exponent
 * - modulus
 */
err_t
unpack_RSA_public_key(struct RSA_public_key *rsa, const chunk_t *pubkey)
{
    chunk_t exponent;
    chunk_t mod;

    rsa->keyid[0] = '\0';	/* in case of keybolbtoid failure */

    if (pubkey->len < 3)
	return "RSA public key blob way to short";	/* not even room for length! */

    rsa->key_rfc3110 = chunk_clone(*pubkey, "rfc3110 format of public key");

    if (pubkey->ptr[0] != 0x00)
    {
	setchunk(exponent, pubkey->ptr + 1, pubkey->ptr[0]);
    }
    else
    {
	setchunk(exponent, pubkey->ptr + 3
	    , (pubkey->ptr[1] << BITS_PER_BYTE) + pubkey->ptr[2]);
    }

    if (pubkey->len - (exponent.ptr - pubkey->ptr) < exponent.len + RSA_MIN_OCTETS_RFC)
	return "RSA public key blob too short";

    mod.ptr = exponent.ptr + exponent.len;
    mod.len = &pubkey->ptr[pubkey->len] - mod.ptr;

    if (mod.len < RSA_MIN_OCTETS)
	return RSA_MIN_OCTETS_UGH;

    if (mod.len > RSA_MAX_OCTETS)
	return RSA_MAX_OCTETS_UGH;

    if (mod.len > pubkey->ptr + pubkey->len - mod.ptr)
       return "RSA public key blob too short";

    n_to_mpz(&rsa->e, exponent.ptr, exponent.len);
    n_to_mpz(&rsa->n, mod.ptr, mod.len);

    keyblobtoid(pubkey->ptr, pubkey->len, rsa->keyid, sizeof(rsa->keyid));

    rsa->k = mpz_sizeinbase(&rsa->n, 2);	/* size in bits, for a start */
    rsa->k = (rsa->k + BITS_PER_BYTE - 1) / BITS_PER_BYTE;	/* now octets */

    if (rsa->k != mod.len)
    {
	mpz_clear(&rsa->e);
	mpz_clear(&rsa->n);
	return "RSA modulus shorter than specified";
    }

    return NULL;
}
コード例 #2
0
ファイル: v2-child.c プロジェクト: hydromet/libreswan
int main(int argc, char *argv[])
{
	struct state st1;

	progname = argv[0];
	cur_debugging = DBG_CRYPT | DBG_KERNEL | DBG_PARSING;

	memset(&st1, 0, sizeof(st1));
	pluto_shared_secrets_file = "../../baseconfigs/east/etc/ipsec.secrets";

	lsw_init_ipsecdir("../../baseconfigs/east/etc/ipsec.d");
	lsw_init_rootdir("../../baseconfigs/east");

	/* initialize list of moduli */
	init_crypto();
	load_lswcrypto();

	init_seam_kernelalgs();

	/* now derive the keys for the CHILD_SA */
	{
		struct ipsec_proto_info *ipi;

		setchunk(st1.st_skey_d, tc3_results_skey_d,
			 sizeof(tc3_results_skey_d));

		ipi = &st1.st_esp;
		ipi->attrs.transattrs.encrypt   = IKEv2_ENCR_AES_CBC;
		ipi->attrs.transattrs.enckeylen = 128;
		ipi->attrs.transattrs.integ_hash = alg_info_esp_v2tov1aa(
			IKEv2_AUTH_HMAC_SHA1_96);

		ikev2_derive_child_keys(&st1);

		DBG_dump("our  keymat: ",
			 ipi->our_keymat,
			 ipi->keymat_len);

		DBG_dump("peer keymat: ",
			 ipi->peer_keymat,
			 ipi->keymat_len);
	}

	exit(0);
}
コード例 #3
0
/* build an ocsp location from certificate information
 * without unsharing its contents
 */
static bool
build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
{
    static u_char digest[SHA1_DIGEST_SIZE];  /* temporary storage */

    location->uri = (cert->accessLocation.ptr != NULL)
	? cert->accessLocation : ocsp_default_uri;

    /* abort if no ocsp location uri is defined */
    if (location->uri.ptr == NULL)
 	return FALSE;

    setchunk(location->authNameID, digest, SHA1_DIGEST_SIZE);
    compute_digest(cert->issuer, OID_SHA1, &location->authNameID);

    location->next = NULL;
    location->issuer = cert->issuer;
    location->authKeyID = cert->authKeyID;
    location->authKeySerialNumber = cert->authKeySerialNumber;
    
    if (cert->authKeyID.ptr == NULL) 
    {
	x509cert_t *authcert = get_authcert(cert->issuer
		, cert->authKeySerialNumber, cert->authKeyID, AUTH_CA);

	if (authcert != NULL)
	{
	    location->authKeyID = authcert->subjectKeyID;
	    location->authKeySerialNumber = authcert->serialNumber;
	}
    }

    location->nonce = empty_chunk;
    location->certinfo = NULL;

    return TRUE;
}
コード例 #4
0
ファイル: ikev2_crypto.c プロジェクト: st3fan/libreswan
void ikev2_derive_child_keys(struct state *st, enum phase1_role role)
{
	struct v2prf_stuff childsacalc;
	
	chunk_t ikeymat,rkeymat;
	struct ipsec_proto_info *ipi = &st->st_esp;
	
	ipi->attrs.transattrs.ei=kernel_alg_esp_info(
		ipi->attrs.transattrs.encrypt, 
		ipi->attrs.transattrs.enckeylen,
		ipi->attrs.transattrs.integ_hash);

	passert(ipi->attrs.transattrs.ei != NULL);
	memset(&childsacalc, 0, sizeof(childsacalc));
	childsacalc.prf_hasher = st->st_oakley.prf_hasher;

	setchunk(childsacalc.ni, st->st_ni.ptr, st->st_ni.len);
	setchunk(childsacalc.nr, st->st_nr.ptr, st->st_nr.len);
	childsacalc.spii.len=0;
	childsacalc.spir.len=0;
	
	childsacalc.counter[0] = 1;
	childsacalc.skeyseed = &st->st_skey_d;
	
	st->st_esp.present = TRUE;
	st->st_esp.keymat_len = st->st_esp.attrs.transattrs.ei->enckeylen+
		st->st_esp.attrs.transattrs.ei->authkeylen;
	
	
/*
 *
 * Keying material MUST be taken from the expanded KEYMAT in the
 * following order:
 *
 *    All keys for SAs carrying data from the initiator to the responder
 *    are taken before SAs going in the reverse direction.
 *
 *    If multiple IPsec protocols are negotiated, keying material is
 *    taken in the order in which the protocol headers will appear in
 *    the encapsulated packet.
 *
 *    If a single protocol has both encryption and authentication keys,
 *    the encryption key is taken from the first octets of KEYMAT and
 *    the authentication key is taken from the next octets.
 *
 */
	
	v2genbytes(&ikeymat, st->st_esp.keymat_len
		   , "initiator keys", &childsacalc);

	v2genbytes(&rkeymat, st->st_esp.keymat_len
		   , "responder keys", &childsacalc);

	/* This should really be role == INITIATOR, but then our keys are
	 * installed reversed. This is a workaround until we locate the
	 * real problem. It's better not to release copies of our code
	 * that will be incompatible with everything else, including our
	 * own updated version
	 * Found by Herbert Xu
	 * if(role == INITIATOR) {
	 */
	if(role != INITIATOR) {
	    DBG(DBG_CRYPT,
		DBG_dump_chunk("our  keymat", ikeymat);
		DBG_dump_chunk("peer keymat", rkeymat);
	    );
コード例 #5
0
ファイル: ikev2_crypto.c プロジェクト: fatenever/libreswan
void ikev2_derive_child_keys(struct state *st, enum original_role role)
{
	chunk_t ikeymat, rkeymat;
	/* ??? note assumption that AH and ESP cannot be combined */
	struct ipsec_proto_info *ipi =
		st->st_esp.present? &st->st_esp :
		st->st_ah.present? &st->st_ah :
		NULL;
	struct esp_info *ei;

	passert(ipi != NULL);	/* ESP or AH must be present */
	passert(st->st_esp.present != st->st_ah.present);	/* only one */

	/* ??? there is no kernel_alg_ah_info */
	/* ??? will this work if the result of kernel_alg_esp_info
	 * is a pointer into its own static buffer (therefore ephemeral)?
	 */
	ei = kernel_alg_esp_info(
		ipi->attrs.transattrs.encrypt,
		ipi->attrs.transattrs.enckeylen,
		ipi->attrs.transattrs.integ_hash);

	passert(ei != NULL);
	ipi->attrs.transattrs.ei = ei;

	/* ipi->attrs.transattrs.integ_hasher->hash_key_size / BITS_PER_BYTE; */
	unsigned authkeylen = ikev1_auth_kernel_attrs(ei->auth, NULL);
	/* ??? no account is taken of AH */
	/* transid is same as esp_ealg_id */
	switch (ei->transid) {
	case IKEv2_ENCR_reserved:
		/* AH */
		ipi->keymat_len = authkeylen;
		break;

	case IKEv2_ENCR_AES_CTR:
		ipi->keymat_len = ei->enckeylen + authkeylen + AES_CTR_SALT_BYTES;;
		break;

	case IKEv2_ENCR_AES_GCM_8:
	case IKEv2_ENCR_AES_GCM_12:
	case IKEv2_ENCR_AES_GCM_16:
		/* aes_gcm does not use an integ (auth) algo - see RFC 4106 */
		ipi->keymat_len = ei->enckeylen + AES_GCM_SALT_BYTES;
		break;

	case IKEv2_ENCR_AES_CCM_8:
	case IKEv2_ENCR_AES_CCM_12:
	case IKEv2_ENCR_AES_CCM_16:
		/* aes_ccm does not use an integ (auth) algo - see RFC 4309 */
		ipi->keymat_len = ei->enckeylen + AES_CCM_SALT_BYTES;
		break;

	default:
		/* ordinary ESP */
		ipi->keymat_len = ei->enckeylen + authkeylen;
		break;
	}

	DBG(DBG_CONTROL,
		DBG_log("enckeylen=%" PRIu32 ", authkeylen=%u, keymat_len=%" PRIu16,
			ei->enckeylen, authkeylen, ipi->keymat_len));

	/*
	 *
	 * Keying material MUST be taken from the expanded KEYMAT in the
	 * following order:
	 *
	 *    All keys for SAs carrying data from the initiator to the responder
	 *    are taken before SAs going in the reverse direction.
	 *
	 *    If multiple IPsec protocols are negotiated, keying material is
	 *    taken in the order in which the protocol headers will appear in
	 *    the encapsulated packet.
	 *
	 *    If a single protocol has both encryption and authentication keys,
	 *    the encryption key is taken from the first octets of KEYMAT and
	 *    the authentication key is taken from the next octets.
	 *
	 *    For AES GCM (RFC 4106 Section 8,1) we need to add 4 bytes for
	 *    salt (AES_GCM_SALT_BYTES)
	 */
	chunk_t ni;
	chunk_t nr;
	setchunk(ni, st->st_ni.ptr, st->st_ni.len);
	setchunk(nr, st->st_nr.ptr, st->st_nr.len);

	PK11SymKey *keymat = ikev2_child_sa_keymat(st->st_oakley.prf_hasher,
						   st->st_skey_d_nss,
						   NULL/*dh*/, ni, nr,
						   ipi->keymat_len * 2);
	PK11SymKey *ikey = key_from_symkey_bytes(keymat, 0, ipi->keymat_len);
	ikeymat = chunk_from_symkey("initiator keys", ikey);
	free_any_symkey("ikey:", &ikey);

	PK11SymKey *rkey = key_from_symkey_bytes(keymat, ipi->keymat_len,
						 ipi->keymat_len);
	rkeymat = chunk_from_symkey("responder keys:", rkey);
	free_any_symkey("rkey:", &rkey);

	free_any_symkey("keymat", &keymat);

	if (role != ORIGINAL_INITIATOR) {
		DBG(DBG_PRIVATE, {
			    DBG_dump_chunk("our  keymat", ikeymat);
			    DBG_dump_chunk("peer keymat", rkeymat);
		    });
コード例 #6
0
ファイル: ikev2_ppk.c プロジェクト: libreswan/libreswan
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);
	}
}