/// @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; }
/// 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); }
/// 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; }