summaryrefslogtreecommitdiff
path: root/src/libpiano/crypt.c
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2012-04-27 15:15:40 +0200
committerLars-Dominik Braun <lars@6xq.net>2012-05-01 11:04:50 +0200
commit63c86dce1e248aa03a99792f56077dc176bcd295 (patch)
treee702be797a6e1b84f780dc6bf3fab504eb853d71 /src/libpiano/crypt.c
parentbd9291bfc016a5f16fd81495dbe779b47627ade0 (diff)
downloadpianobar-windows-63c86dce1e248aa03a99792f56077dc176bcd295.tar.gz
pianobar-windows-63c86dce1e248aa03a99792f56077dc176bcd295.tar.bz2
pianobar-windows-63c86dce1e248aa03a99792f56077dc176bcd295.zip
piano: Move to JSON API (v5)
In random order: Thanks to Chris Eby for his work on pithos, to an anonymous coward for sending me his Android client, to Alex Howard for sending me the webOS client, to ZigZagJoe for providing a temporary fix and thanks to everyone who sent Pandora a message. Although there are a few rough edges here and there this fixes #236.
Diffstat (limited to 'src/libpiano/crypt.c')
-rw-r--r--src/libpiano/crypt.c205
1 files changed, 51 insertions, 154 deletions
diff --git a/src/libpiano/crypt.c b/src/libpiano/crypt.c
index 3f98f42..6dafcca 100644
--- a/src/libpiano/crypt.c
+++ b/src/libpiano/crypt.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2008-2011
+Copyright (c) 2008-2012
Lars-Dominik Braun <lars@6xq.net>
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -22,23 +22,13 @@ THE SOFTWARE.
*/
#include <string.h>
+#include <assert.h>
+#include <gcrypt.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
-#include <arpa/inet.h>
#include "crypt.h"
-#include "crypt_key_output.h"
-#include "crypt_key_input.h"
-#include "piano_private.h"
-
-#define byteswap32(x) ((((x) >> 24) & 0x000000ff) | \
- (((x) >> 8) & 0x0000ff00) | \
- (((x) << 8) & 0x00ff0000) | \
- (((x) << 24) & 0xff000000))
-
-#define hostToBigEndian32(x) htonl(x)
-#define bigToHostEndian32(x) ntohl(x)
/* decrypt hex-encoded, blowfish-crypted string: decode 2 hex-encoded blocks,
* decrypt, byteswap
@@ -46,162 +36,69 @@ THE SOFTWARE.
* @param decrypted string length (without trailing NUL)
* @return decrypted string or NULL
*/
-#define INITIAL_SHIFT 28
-#define SHIFT_DEC 4
-char *PianoDecryptString (const char * const s, size_t * const retSize) {
- const unsigned char *strInput = (const unsigned char *) s;
- /* hex-decode => strlen/2 + null-byte */
- uint32_t *iDecrypt;
- size_t decryptedSize;
- char *strDecrypted;
- unsigned char shift = INITIAL_SHIFT, intsDecoded = 0, j;
- /* blowfish blocks, 32-bit */
- uint32_t f, l, r, lrExchange;
-
- decryptedSize = strlen ((const char *) strInput)/2;
- if ((iDecrypt = calloc (decryptedSize/sizeof (*iDecrypt)+1,
- sizeof (*iDecrypt))) == NULL) {
- return NULL;
- }
- strDecrypted = (char *) iDecrypt;
-
- while (*strInput != '\0') {
- /* hex-decode string */
- if (*strInput >= '0' && *strInput <= '9') {
- *iDecrypt |= (*strInput & 0x0f) << shift;
- } else if (*strInput >= 'a' && *strInput <= 'f') {
- /* 0xa (hex) = 10 (decimal), 'a' & 0x0f == 1 => +9 */
- *iDecrypt |= ((*strInput+9) & 0x0f) << shift;
- }
- if (shift > 0) {
- shift -= SHIFT_DEC;
- } else {
- shift = INITIAL_SHIFT;
- /* initialize next dword */
- *(++iDecrypt) = 0;
- ++intsDecoded;
- }
-
- /* two 32-bit hex-decoded boxes available => blowfish decrypt */
- if (intsDecoded == 2) {
- l = *(iDecrypt-2);
- r = *(iDecrypt-1);
-
- for (j = in_key_n + 1; j > 1; --j) {
- l ^= in_key_p [j];
-
- f = in_key_s [0][(l >> 24) & 0xff] +
- in_key_s [1][(l >> 16) & 0xff];
- f ^= in_key_s [2][(l >> 8) & 0xff];
- f += in_key_s [3][l & 0xff];
- r ^= f;
- /* exchange l & r */
- lrExchange = l;
- l = r;
- r = lrExchange;
- }
- /* exchange l & r */
- lrExchange = l;
- l = r;
- r = lrExchange;
- r ^= in_key_p [1];
- l ^= in_key_p [0];
-
- *(iDecrypt-2) = bigToHostEndian32 (l);
- *(iDecrypt-1) = bigToHostEndian32 (r);
-
- intsDecoded = 0;
- }
- ++strInput;
+char *PianoDecryptString (const char * const input, size_t * const retSize) {
+ size_t inputLen = strlen (input);
+ gcry_error_t gret;
+ unsigned char *output;
+ size_t outputLen = inputLen/2;
+
+ assert (inputLen%2 == 0);
+
+ output = calloc (outputLen+1, sizeof (*output));
+ /* hex decode */
+ for (size_t i = 0; i < outputLen; i++) {
+ char hex[3];
+ memcpy (hex, &input[i*2], 2);
+ hex[2] = '\0';
+ output[i] = strtol (hex, NULL, 16);
}
- if (retSize != NULL) {
- *retSize = decryptedSize;
+ gcry_cipher_hd_t h;
+ gcry_cipher_open (&h, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 0);
+ gcry_cipher_setkey (h, (unsigned char *) "R=U!LH$O2B#", 11);
+ gret = gcry_cipher_decrypt (h, output, outputLen, NULL, 0);
+ if (gret) {
+ fprintf (stderr, "Failure: %s/%s\n", gcry_strsource (gret), gcry_strerror (gret));
+ return NULL;
}
- return strDecrypted;
+ gcry_cipher_close (h);
+ *retSize = outputLen;
+
+ return (char *) output;
}
-#undef INITIAL_SHIFT
-#undef SHIFT_DEC
/* blowfish-encrypt/hex-encode string
* @param encrypt this
* @return encrypted, hex-encoded string
*/
char *PianoEncryptString (const char *s) {
- const unsigned char *strInput = (const unsigned char *) s;
- const size_t strInputN = strlen ((const char *) strInput);
- /* num of 64-bit blocks, rounded to next block */
- size_t blockN = strInputN / 8 + 1;
- uint32_t *blockInput, *blockPtr;
- /* output string */
- unsigned char *strHex, *hexPtr;
- const char *hexmap = "0123456789abcdef";
-
- if ((blockInput = calloc (blockN*2, sizeof (*blockInput))) == NULL) {
+ unsigned char *paddedInput, *hexOutput;
+ size_t inputLen = strlen (s);
+ /* blowfish expects two 32 bit blocks */
+ size_t paddedInputLen = (inputLen % 8 == 0) ? inputLen : inputLen + (8-inputLen%8);
+ gcry_error_t gret;
+
+ paddedInput = calloc (paddedInputLen+1, sizeof (*paddedInput));
+ memcpy (paddedInput, s, inputLen);
+
+ gcry_cipher_hd_t h;
+ gcry_cipher_open (&h, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB, 0);
+ gcry_cipher_setkey (h, (unsigned char *) "6#26FRL$ZWD", 11);
+ gret = gcry_cipher_encrypt (h, paddedInput, paddedInputLen, NULL, 0);
+ if (gret) {
+ fprintf (stderr, "Failure: %s/%s\n", gcry_strsource (gret), gcry_strerror (gret));
return NULL;
}
- blockPtr = blockInput;
- if ((strHex = calloc (blockN*8*2 + 1, sizeof (*strHex))) == NULL) {
- return NULL;
- }
- hexPtr = strHex;
-
- memcpy (blockInput, strInput, strInputN);
-
- while (blockN > 0) {
- /* encryption blocks */
- uint32_t f, lrExchange;
- register uint32_t l, r;
- int i;
-
- l = hostToBigEndian32 (*blockPtr);
- r = hostToBigEndian32 (*(blockPtr+1));
-
- /* encrypt blocks */
- for (i = 0; i < out_key_n; i++) {
- l ^= out_key_p[i];
-
- f = out_key_s[0][(l >> 24) & 0xff] +
- out_key_s[1][(l >> 16) & 0xff];
- f ^= out_key_s[2][(l >> 8) & 0xff];
- f += out_key_s[3][l & 0xff];
- r ^= f;
- /* exchange l & r */
- lrExchange = l;
- l = r;
- r = lrExchange;
- }
- /* exchange l & r again */
- lrExchange = l;
- l = r;
- r = lrExchange;
- r ^= out_key_p [out_key_n];
- l ^= out_key_p [out_key_n+1];
-
- /* swap bytes again... */
- l = byteswap32 (l);
- r = byteswap32 (r);
-
- /* hex-encode encrypted blocks */
- for (i = 0; i < 4; i++) {
- *hexPtr++ = hexmap[(l & 0xf0) >> 4];
- *hexPtr++ = hexmap[l & 0x0f];
- l >>= 8;
- }
- for (i = 0; i < 4; i++) {
- *hexPtr++ = hexmap[(r & 0xf0) >> 4];
- *hexPtr++ = hexmap[r & 0x0f];
- r >>= 8;
- }
-
- /* two! 32-bit blocks encrypted (l & r) */
- blockPtr += 2;
- --blockN;
+ hexOutput = calloc (paddedInputLen*2+1, sizeof (*hexOutput));
+ for (size_t i = 0; i < paddedInputLen; i++) {
+ snprintf ((char * restrict) &hexOutput[i*2], 3, "%02x", paddedInput[i]);
}
- free (blockInput);
+ gcry_cipher_close (h);
+ free (paddedInput);
- return (char *) strHex;
+ return (char *) hexOutput;
}
+