diff libpurple/plugins/perl/common/Cipher.xs @ 23655:af603a54ae5a

Some Perl bindings fixes and additions from Zsombor Welker. Technically some of these change the API, but in those couple cases, the way it is now is either broken, not usable or pretty unlikely to be used. Feel free to yell at me and/or revert this if you think this is unacceptable. Fixes #5912
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 07 Aug 2008 02:48:21 +0000
parents 2f8274ce570a
children 907f5f41e32a
line wrap: on
line diff
--- a/libpurple/plugins/perl/common/Cipher.xs	Thu Aug 07 01:46:36 2008 +0000
+++ b/libpurple/plugins/perl/common/Cipher.xs	Thu Aug 07 02:48:21 2008 +0000
@@ -3,6 +3,49 @@
 MODULE = Purple::Cipher  PACKAGE = Purple::Cipher  PREFIX = purple_cipher_
 PROTOTYPES: ENABLE
 
+BOOT:
+{
+	HV *stash = gv_stashpv("Purple::Cipher::BatchMode", 1);
+	HV *cipher_caps = gv_stashpv("Purple::Cipher::Caps", 1);
+
+	static const constiv *civ, const_iv[] = {
+#define const_iv(name) {#name, (IV)PURPLE_CIPHER_BATCH_MODE_##name}
+		const_iv(ECB),
+		const_iv(CBC),
+#undef const_iv
+	};
+
+	static const constiv bm_const_iv[] = {
+#define const_iv(name) {#name, (IV)PURPLE_CIPHER_CAPS_##name}
+		const_iv(SET_OPT),
+		const_iv(GET_OPT),
+		const_iv(INIT),
+		const_iv(RESET),
+		const_iv(UNINIT),
+		const_iv(SET_IV),
+		const_iv(APPEND),
+		const_iv(DIGEST),
+		const_iv(ENCRYPT),
+		const_iv(DECRYPT),
+		const_iv(SET_SALT),
+		const_iv(GET_SALT_SIZE),
+		const_iv(SET_KEY),
+		const_iv(GET_KEY_SIZE),
+		const_iv(SET_BATCH_MODE),
+		const_iv(GET_BATCH_MODE),
+		const_iv(GET_BLOCK_SIZE),
+		const_iv(SET_KEY_WITH_LEN),
+		const_iv(UNKNOWN),
+#undef const_iv
+	};
+
+	for (civ = const_iv + sizeof(const_iv) / sizeof(const_iv[0]); civ-- > const_iv; )
+		newCONSTSUB(stash, (char *)civ->name, newSViv(civ->iv));
+
+	for (civ = bm_const_iv + sizeof(bm_const_iv) / sizeof(bm_const_iv[0]); civ-- > bm_const_iv; )
+		newCONSTSUB(cipher_caps, (char *)civ->name, newSViv(civ->iv));
+}
+
 const gchar *
 purple_cipher_get_name(cipher)
 	Purple::Cipher cipher
@@ -11,14 +54,51 @@
 purple_cipher_get_capabilities(cipher)
 	Purple::Cipher cipher
 
-gboolean
-purple_cipher_digest_region(name, data, data_len, in_len, digest, out_len)
-	const gchar * name
-	const guchar * data
-	size_t data_len
+size_t
+purple_cipher_digest_region(name, data_sv, in_len, digest)
+	const gchar *name
+	SV *data_sv
 	size_t in_len
-	guchar &digest
-	size_t * out_len
+	SV *digest
+	PREINIT:
+		gboolean ret;
+		guchar *buff = NULL;
+		guchar *data = NULL;
+		size_t data_len;
+	CODE:
+		data = SvPV(data_sv, data_len);
+		SvUPGRADE(digest, SVt_PV);
+		buff = SvGROW(digest, in_len);
+		ret = purple_cipher_digest_region(name, data, data_len, in_len, buff, &RETVAL);
+		if(!ret) {
+			SvSetSV_nosteal(digest, &PL_sv_undef);
+			XSRETURN_UNDEF;
+		}
+		SvCUR_set(digest, RETVAL);
+		SvPOK_only(digest);
+	OUTPUT:
+		RETVAL
+
+gchar_own*
+purple_cipher_http_digest_calculate_response(algorithm, method, digest_uri, qop, entity, nonce, nonce_count, client_nonce, session_key)
+	const gchar* algorithm
+	const gchar* method
+	const gchar* digest_uri
+	const gchar* qop
+	const gchar* entity
+	const gchar* nonce
+	const gchar* nonce_count
+	const gchar* client_nonce
+	const gchar* session_key
+
+gchar_own*
+purple_cipher_http_digest_calculate_session_key(algorithm, username, realm, password, nonce, client_nonce)
+	const gchar* algorithm
+	const gchar* username
+	const gchar* realm
+	const gchar* password
+	const gchar* nonce
+	const gchar* client_nonce
 
 MODULE = Purple::Cipher  PACKAGE = Purple::Ciphers  PREFIX = purple_ciphers_
 PROTOTYPES: ENABLE
@@ -69,17 +149,19 @@
 	gchar *name
 
 Purple::Cipher::Context
-purple_cipher_context_new(cipher, extra)
+purple_cipher_context_new(klass, cipher, extra = NULL)
 	Purple::Cipher cipher
 	void *extra
+	C_ARGS: cipher, extra
 
 Purple::Cipher::Context
-purple_cipher_context_new_by_name(name, extra)
+purple_cipher_context_new_by_name(klass, name, extra = NULL)
 	gchar *name
 	void *extra
+	C_ARGS: name, extra
 
 void
-purple_cipher_context_reset(context, extra)
+purple_cipher_context_reset(context, extra = NULL)
 	Purple::Cipher::Context context
 	gpointer extra
 
@@ -88,46 +170,103 @@
 	Purple::Cipher::Context context
 
 void
-purple_cipher_context_set_iv(context, iv, len)
-	Purple::Cipher::Context context
-	guchar * iv
-	size_t len
+purple_cipher_context_set_iv(Purple::Cipher::Context context, guchar *iv, size_t length(iv))
+	PROTOTYPE: $$
 
 void
-purple_cipher_context_append(context, data, len)
+purple_cipher_context_append(Purple::Cipher::Context context, guchar *data, size_t length(data))
+	PROTOTYPE: $$
+
+size_t
+purple_cipher_context_digest(context, in_len, digest)
 	Purple::Cipher::Context context
-	guchar * data
-	size_t len
+	size_t in_len
+	SV *digest
+	PREINIT:
+		gboolean ret;
+		guchar *buff = NULL;
+	CODE:
+		SvUPGRADE(digest, SVt_PV);
+		buff = SvGROW(digest, in_len);
+		ret = purple_cipher_context_digest(context, in_len, buff, &RETVAL);
+		if(!ret) {
+			SvSetSV_nosteal(digest, &PL_sv_undef);
+			XSRETURN_UNDEF;
+		}
+		SvCUR_set(digest, RETVAL);
+		SvPOK_only(digest);
+	OUTPUT:
+		RETVAL
 
-gboolean
-purple_cipher_context_digest(context, in_len, digest, out_len)
+size_t
+purple_cipher_context_digest_to_str(context, in_len, digest_s)
 	Purple::Cipher::Context context
 	size_t in_len
-	guchar &digest
-	size_t &out_len
-
-gboolean
-purple_cipher_context_digest_to_str(context, in_len, digest_s, out_len)
-	Purple::Cipher::Context context
-	size_t in_len
-	gchar &digest_s
-	size_t &out_len
+	SV *digest_s
+	PREINIT:
+		gboolean ret;
+		gchar *buff = NULL;
+	CODE:
+		in_len += 1; /* perl shouldn't need to care about '\0' at the end */
+		SvUPGRADE(digest_s, SVt_PV);
+		buff = SvGROW(digest_s, in_len);
+		ret = purple_cipher_context_digest_to_str(context, in_len, buff, &RETVAL);
+		if(!ret) {
+			SvSetSV_nosteal(digest_s, &PL_sv_undef);
+			XSRETURN_UNDEF;
+		}
+		SvCUR_set(digest_s, RETVAL);
+		SvPOK_only(digest_s);
+	OUTPUT:
+		RETVAL
 
 gint
-purple_cipher_context_encrypt(context, data, len, output, outlen)
+purple_cipher_context_encrypt(context, data_sv, output, OUTLIST size_t outlen)
 	Purple::Cipher::Context context
-	guchar &data
-	size_t len
-	guchar &output
-	size_t &outlen
+	SV *data_sv
+	SV *output
+	PROTOTYPE: $$$
+	PREINIT:
+		size_t datalen;
+		guchar *buff = NULL;
+		guchar *data = NULL;
+	CODE:
+		data = SvPV(data_sv, datalen);
+		SvUPGRADE(output, SVt_PV);
+		buff = SvGROW(output, datalen);
+		RETVAL = purple_cipher_context_encrypt(context, data, datalen, buff, &outlen);
+		if(outlen != 0) {
+			SvPOK_only(output);
+			SvCUR_set(output, outlen);
+		} else {
+			SvSetSV_nosteal(output, &PL_sv_undef);
+		}
+	OUTPUT:
+		RETVAL
 
 gint
-purple_cipher_context_decrypt(context, data, len, output, outlen)
+purple_cipher_context_decrypt(context, data_sv, output, OUTLIST size_t outlen)
 	Purple::Cipher::Context context
-	guchar &data
-	size_t len
-	guchar &output
-	size_t &outlen
+	SV *data_sv
+	SV *output
+	PROTOTYPE: $$$
+	PREINIT:
+		size_t datalen;
+		guchar *buff = NULL;
+		guchar *data = NULL;
+	CODE:
+		data = SvPV(data_sv, datalen);
+		SvUPGRADE(output, SVt_PV);
+		buff = SvGROW(output, datalen);
+		RETVAL = purple_cipher_context_decrypt(context, data, datalen, buff, &outlen);
+		if(outlen != 0) {
+			SvPOK_only(output);
+			SvCUR_set(output, outlen);
+		} else {
+			SvSetSV_nosteal(output, &PL_sv_undef);
+		}
+	OUTPUT:
+		RETVAL
 
 void
 purple_cipher_context_set_salt(context, salt)
@@ -155,3 +294,21 @@
 gpointer
 purple_cipher_context_get_data(context)
 	Purple::Cipher::Context context
+
+Purple::Cipher::BatchMode
+purple_cipher_context_get_batch_mode(context)
+	Purple::Cipher::Context context
+
+size_t
+purple_cipher_context_get_block_size(context)
+	Purple::Cipher::Context context
+
+void
+purple_cipher_context_set_batch_mode(context, mode)
+	Purple::Cipher::Context context
+	Purple::Cipher::BatchMode mode
+
+void
+purple_cipher_context_set_key_with_len(Purple::Cipher::Context context, guchar *key, size_t length(key))
+	PROTOTYPE: $$
+