Exemple #1
0
/// @ref CryptCurve25519 function to check if a given curve25519 key id is valid
/// This name might come from a bad guy, so let's carefully scrub the name
FSTATIC gboolean
_is_valid_curve25519_key_id(const char * key_id,	///< key_id to validate
			     enum keytype ktype)	///< which kind of key is it?
{
	if (!_is_legal_curve25519_key_id(key_id)) {
		return FALSE;
	}
	if (_cache_curve25519_keypair(key_id)) {
		if (ktype == PRIVATEKEY) {
			return cryptframe_private_key_by_id(key_id) != NULL;
		}
		return TRUE;
	}
	return FALSE;
}
/// Set the default signing key
WINEXPORT void
cryptframe_set_signing_key_id(const char * key_id)
{
	CryptFramePrivateKey*	secret_key = cryptframe_private_key_by_id(key_id);
	if (secret_key) {
		if (default_signing_key) {
			UNREF(default_signing_key);
			default_signing_key = NULL;
		}
		REF(secret_key);
		default_signing_key = secret_key;
	}else{
		g_warning("%s.%d: Cannot set signing key to [%s] - no such private key"
		,	__FUNCTION__, __LINE__, key_id);
	}
}
/// Create a new private key - or return the existing private key with this id
WINEXPORT CryptFramePrivateKey*
cryptframe_privatekey_new(const char *key_id,	///<[in] Key id of given private key
			  gpointer private_key)	///<[in] MALLOCed private key
{
	AssimObj*		aself;
	CryptFramePrivateKey*	self;
	INITMAPS;
	g_return_val_if_fail(key_id != NULL && private_key != NULL, NULL);
	self = cryptframe_private_key_by_id(key_id);
	if (self) {
		g_warning("%s.%d: Private key %s Already IN private key map", __FUNCTION__, __LINE__, key_id);
		return self;
	}
	aself = assimobj_new(sizeof(CryptFramePrivateKey));
	aself->_finalize = _cryptframe_privatekey_finalize;
	self = NEWSUBCLASS(CryptFramePrivateKey, aself);
	self->key_id = g_strdup(key_id);
	self->key_size = crypto_box_SECRETKEYBYTES;
	self->private_key = private_key;
	g_hash_table_insert(private_key_map, self->key_id, self);
	DEBUGCKSUM3(self->key_id, private_key);
	return self;
}
Exemple #4
0
/// Given marshalled packet data corresponding to an CryptCurve25519 frame
/// return the corresponding Frame
/// In other words, un-marshall the data...
/// In our case, this means we decrypt it in-place into many other frames...
WINEXPORT Frame*
cryptcurve25519_tlvconstructor(gpointer tlvstart,	///<[in/out] Start of marshalled CStringFrame data
			  gconstpointer pktend,		///<[in] Pointer to first invalid byte past 'tlvstart'
		          gpointer* ignorednewpkt,	///<[ignored] replacement packet
		          gpointer* ignoredpktend)	///<[ignored] end of replacement packet
{
	guint8*			valptr = get_generic_tlv_nonconst_value(tlvstart, pktend);
	guint8*			nonce;
	guint8*			cyphertext;
	const guint8*		tlvend8 = valptr + get_generic_tlv_len(tlvstart, pktend);
	guint8*			plaintext;
	CryptCurve25519*	ret;
	guint			namelen;
	gsize			cypherlength;
				// The first key name is in sender's key name
				// The second key name is in receiver's key name
	CryptFramePublicKey *	sender_public_key = NULL;
	CryptFramePrivateKey*	receiver_secret_key = NULL;
	const char*		sender_pubkey_id = NULL;
	const char*		rcvr_seckey_id = NULL;
	int			j;

	(void)ignorednewpkt; (void)ignoredpktend;
	valptr = get_generic_tlv_nonconst_value(tlvstart, pktend);
	for (j=0; j < 2; ++j) {
		char *	key_id;
		g_return_val_if_fail((gpointer)(valptr+2) <= pktend, NULL);
		namelen = tlv_get_guint8(valptr, pktend);
		valptr += 1;
		g_return_val_if_fail((gpointer)(valptr+namelen) <= pktend, NULL);
		key_id = (char *)valptr;
		g_return_val_if_fail (strnlen(key_id, namelen) == namelen -1, NULL);
		g_return_val_if_fail(_is_valid_curve25519_key_id(key_id
		, 	0 == j ? PUBLICKEY : PRIVATEKEY), NULL);
		if (0 == j) {
			sender_public_key = cryptframe_public_key_by_id(key_id);
			sender_pubkey_id = key_id;
		}else{
			receiver_secret_key = cryptframe_private_key_by_id(key_id);
			rcvr_seckey_id = key_id;
		}
		g_return_val_if_fail(key_id != NULL, NULL);
		valptr += namelen;
	}
	if (NULL == sender_public_key) {
		g_warning("%s.%d: No access to sender %s public key"
		,	__FUNCTION__, __LINE__, sender_pubkey_id);
		return NULL;
	}
	if (NULL == receiver_secret_key) {
		g_warning("%s.%d: No access to receiver %s private key"
		,	__FUNCTION__, __LINE__, rcvr_seckey_id);
		return NULL;
	}
	g_return_val_if_fail((gpointer)(valptr + (crypto_box_NONCEBYTES+crypto_box_MACBYTES)) <= pktend, NULL);
	nonce = valptr;
	cyphertext = nonce + crypto_box_NONCEBYTES;
	plaintext = cyphertext + crypto_box_MACBYTES;
	cypherlength = tlvend8 - cyphertext;
	DEBUGCKSUM4("nonce:", nonce, crypto_box_NONCEBYTES);
	DEBUGCKSUM4("sender   public key :", sender_public_key -> public_key,  crypto_box_PUBLICKEYBYTES);
	DEBUGCKSUM4("receiver private key:", receiver_secret_key->private_key, crypto_box_SECRETKEYBYTES);
	DEBUGMSG4("cypher offset versus tlvstart: %ld", (long)(cyphertext-(guint8*)tlvstart));
	DEBUGCKSUM4("cypher text:", cyphertext, cypherlength);
	if (crypto_box_open_easy(plaintext, cyphertext, cypherlength, nonce
	,	sender_public_key->public_key, receiver_secret_key->private_key) != 0) {
		g_warning("%s.%d: could not decrypt %d byte message encrypted with key pair [pub:%s, sec:%s]"
		,	__FUNCTION__, __LINE__, (int)cypherlength, sender_pubkey_id, rcvr_seckey_id);
		return NULL;
	}
	DEBUGCKSUM4("plain text:", plaintext, cypherlength-crypto_box_MACBYTES);
	// Note that our return value's size will determine where the beginning of the
	// decrypted data is (according to it's dataspace() member function)
	ret = cryptcurve25519_new(get_generic_tlv_type(tlvstart, pktend)
	,	(const char *)sender_pubkey_id
	,	rcvr_seckey_id, FALSE, 0);
	return (ret ? &(ret->baseclass.baseclass) : NULL);
}
Exemple #5
0
/// Construct a new CryptCurve25519 object (frame).
CryptCurve25519*
cryptcurve25519_new(guint16 frame_type,	///<[in] TLV type of CryptCurve25519
	  const char * sender_key_id,	///<[in] name of sender's key
	  const char * receiver_key_id,	///<[in] name of receiver's key
	  gboolean     forsending,	///<[in] TRUE if this is for sending
	  gsize objsize)		///<[in] sizeof(this object) - or zero for default
{
	CryptFrame*		baseframe;
	CryptCurve25519*	ret;

	BINDDEBUG(CryptCurve25519);
	if (objsize < sizeof(CryptCurve25519)) {
		objsize = sizeof(CryptCurve25519);
	}
	if (NULL == sender_key_id) {
		sender_key_id = cryptframe_get_signing_key_id();
	}
	DEBUGMSG2("%s.%d:(%s, %s, %d)", __FUNCTION__, __LINE__, sender_key_id, receiver_key_id
	,	(int)objsize);
	g_return_val_if_fail(sender_key_id != NULL && receiver_key_id != NULL, NULL);
	if (!_is_valid_curve25519_key_id(receiver_key_id, PUBLICKEY)) {
		g_critical("%s.%d: public key name [%s] is invalid", __FUNCTION__, __LINE__, receiver_key_id);
		return NULL;
	}
	if (!_is_valid_curve25519_key_id(sender_key_id, PUBLICKEY)) {
		g_critical("%s.%d: public key name [%s] is invalid", __FUNCTION__, __LINE__, sender_key_id);
		return NULL;
	}
	baseframe = cryptframe_new(frame_type, sender_key_id, receiver_key_id, objsize);
	if (!_parentclass_finalize) {
		_parentclass_finalize = baseframe->baseclass.baseclass._finalize;
	}
	baseframe->baseclass.isvalid	= _cryptcurve25519_default_isvalid;
	baseframe->baseclass.updatedata	= _cryptcurve25519_updatedata;
	baseframe->baseclass.length	= TLVLEN(receiver_key_id, sender_key_id);
	baseframe->baseclass.baseclass._finalize = _cryptcurve25519_finalize;
	ret			= NEWSUBCLASS(CryptCurve25519, baseframe);
	ret->forsending		= forsending;
	ret->private_key	= cryptframe_private_key_by_id(forsending ? sender_key_id : receiver_key_id);
	ret->public_key		= cryptframe_public_key_by_id(forsending ? receiver_key_id : sender_key_id);
	if (ret->private_key && ret->public_key) {
		DEBUGCKSUM3("private_key:", ret->private_key->private_key, crypto_box_SECRETKEYBYTES);
		DEBUGCKSUM3("public_key:", ret->public_key->public_key, crypto_box_PUBLICKEYBYTES);
		DUMP3(__FUNCTION__, &ret->baseclass.baseclass.baseclass, " is return value");
		REF(ret->private_key);
		REF(ret->public_key);
	}else{
		if (!ret->private_key) {
			g_warning("%s.%d: Sender private key is NULL for key id %s", __FUNCTION__, __LINE__
			,	sender_key_id);
			abort();
		}
		if (!ret->public_key) {
			g_warning("%s.%d: Receiver public key is NULL for key id %s", __FUNCTION__, __LINE__
			,	receiver_key_id);
		}
		UNREF3(ret);
		return NULL;
	}
	return ret;
}