diff options
-rw-r--r-- | intern/keymaker/Makefile | 85 | ||||
-rw-r--r-- | intern/keymaker/key.c | 489 | ||||
-rw-r--r-- | intern/keymaker/key.h | 83 | ||||
-rw-r--r-- | intern/keymaker/key_internal.h | 89 | ||||
-rw-r--r-- | intern/keymaker/keyloader.c | 315 | ||||
-rw-r--r-- | intern/keymaker/mt19937int.c | 130 | ||||
-rw-r--r-- | intern/keymaker/mt19937int.h | 45 | ||||
-rw-r--r-- | intern/keymaker/python/key_pyc.h | 153 |
8 files changed, 1389 insertions, 0 deletions
diff --git a/intern/keymaker/Makefile b/intern/keymaker/Makefile new file mode 100644 index 00000000000..a82c9e7c9b8 --- /dev/null +++ b/intern/keymaker/Makefile @@ -0,0 +1,85 @@ +# +# $Id$ +# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# blender keyreader-library makefile +# + +LIBNAME = blenkey +SOURCEDIR = intern/$(LIBNAME) +DIR = $(OCGDIR)/$(SOURCEDIR) +CSRCS = mt19937int.c key.c + +ALLTARGETS = $(OBJS) + +include nan_compile.mk + +CFLAGS += $(LEVEL_2_C_WARNINGS) + +CPPFLAGS += -I$(NAN_OPENSSL)/include -Ipython/ + +include nan_link.mk + +# OBJS is for the library, set by nan_compile.mk +LOADER_OBJS = $(DIR)/$(DEBUG_DIR)keyloader.o + +ifneq ($(OS),windows) + LIBS = $(NAN_OPENSSL)/lib/libcrypto.a +else + LIBS = $(NAN_OPENSSL)/lib/libeay32.lib + LIBS += advapi32.lib gdi32.lib +endif + +all debug:: link + +link: $(DIR)/$(DEBUG_DIR)keyloader + +strip: + ifneq ($(OS),windows) + strip keyloader + @ls -la keyloader + else + @ls -la keyloader.exe + endif + +install: all debug + @[ -d $(LCGDIR)/$(LIBNAME) ] || mkdir $(LCGDIR)/$(LIBNAME) + @[ -d $(LCGDIR)/$(LIBNAME)/include ] || mkdir $(LCGDIR)/$(LIBNAME)/include + @[ -d $(LCGDIR)/$(LIBNAME)/lib ] || mkdir $(LCGDIR)/$(LIBNAME)/lib + cp -f key.h $(LCGDIR)/$(LIBNAME)/include/blenkey.h + cp -f $(LIB_a) $(LCGDIR)/$(LIBNAME)/lib/ + +$(DIR)/$(DEBUG_DIR)keyloader: $(LOADER_OBJS) $(LIB_a) + $(CC) $(LDFLAGS) -o $@ $(LOADER_OBJS) $(LIB_a) $(LIBS) + +clean:: + $(RM) $(DIR)/key* $(DIR)/debug/key* + $(RM) $(DIR)/nan* $(DIR)/debug/nan* + +tags: + etags *.c *.h diff --git a/intern/keymaker/key.c b/intern/keymaker/key.c new file mode 100644 index 00000000000..56df96c16fd --- /dev/null +++ b/intern/keymaker/key.c @@ -0,0 +1,489 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +// ex:ts=4 + +/** + * $Id$ + * Copyright (C) 2001 NaN Technologies B.V. + * Blender Key loader library + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "key.h" // external interface +#include "key_internal.h" + +char *Hexify(byte *in, unsigned int length) { + unsigned int i; + char Tstring[3]; + char *out = malloc((2*length + 1) * sizeof(char)); + sprintf(out, "%02X", in[0]); + for (i=1; i<length; i++) { + sprintf(Tstring, "%02X", in[i]); + strcat(out, Tstring); + } + return (out); +} + +byte *DeHexify(char *in) { + size_t len = strlen(in); + byte *out = malloc((len/2) * sizeof(byte)); + unsigned int hexedbyte; + unsigned int i; + char *inp = in; + byte *outp = out; + for (i=0; i<(len/2); i++) { + sscanf(inp, "%2x", &hexedbyte); + inp += 2; + *outp = (byte) hexedbyte; + outp++; + } + // printf("\nlen=%d, string=[%s]\n", len, Hexify(out, len/2)); + return (out); +} + +int from_hex(char c) { + return (c<'A') ? (c-'0') : (c-'A'+10); +} + +// 5 ReadHex helper functions ------------------------------------------ +// read one Hex byte (two characters) and skip newlines if necessary +byte ReadHexByteFp(FILE *fh, int *newlinetracker) { + unsigned char a; + unsigned char a1, a2; + // read 2 bytes hexcode of ascii data type + fread(&a1, 1, 1, fh); + fread(&a2, 1, 1, fh); + a = 16 * (from_hex(a1)) + (from_hex(a2)); + //printf("Char[%d] = %02X\n", *newlinetracker, a); + *newlinetracker += 2; + // skip the newlines + if (*newlinetracker == 72) { + fseek(fh, 1, SEEK_CUR); + *newlinetracker = 0; + //printf("LastChar = %02X\n", a); + } + return((byte) a); +} +byte ReadHexByteCp(char **from) { + int a; + // read 2 bytes hexcode of ascii data type + sscanf(*from, "%2x", &a); + //printf("Char = %02X\n", a); + *from += 2; + return((byte) a); +} +// Generic hex2int +int HexToInt(int a) { + if (a == 0x20) // space, count as 0 ;-) + return 0; + else + return(a - '0'); +} +// Note: this is only to be used for the header type +int HexToIntFp(FILE *fh, int *newlinetracker) { + byte a = ReadHexByteFp(fh, newlinetracker); + if (DEBUG) printf("%02X = %d\n", a, a); // note: no HexToInt here + return(a); +} +int HexToIntCp(char **from) { + byte a = ReadHexByteCp(from); + if (DEBUG) printf("%02X = %d\n", a, a); // note: no HexToInt here + return(a); +} +// Note: this is only to be used for the header length +int Hex5ToInt(byte a, byte b, byte c, byte d, byte e) { + return(HexToInt((int) a) * 10000 + + HexToInt((int) b) * 1000 + + HexToInt((int) c) * 100 + + HexToInt((int) d) * 10 + + HexToInt((int) e)); +} +// Note: this is only to be used for the header length +int Hex5ToIntFp(FILE *fh, int *newlinetracker) { + byte a = ReadHexByteFp(fh, newlinetracker), + b = ReadHexByteFp(fh, newlinetracker), + c = ReadHexByteFp(fh, newlinetracker), + d = ReadHexByteFp(fh, newlinetracker), + e = ReadHexByteFp(fh, newlinetracker); + if (DEBUG) printf("\n%02X%02X%02X%02X%02X = %d\n", a, b, c, d, e, + Hex5ToInt(a, b, c, d, e)); + return(Hex5ToInt(a, b, c, d, e)); +} +int Hex5ToIntCp(char **from) { + byte a = ReadHexByteCp(from), + b = ReadHexByteCp(from), + c = ReadHexByteCp(from), + d = ReadHexByteCp(from), + e = ReadHexByteCp(from); + if (DEBUG) printf("\n%02X%02X%02X%02X%02X = %d\n", a, b, c, d, e, + Hex5ToInt(a, b, c, d, e)); + return(Hex5ToInt(a, b, c, d, e)); +} +// --------------------------------------------------------------------- + +// return the biggest +byte checkfunc0(byte a, byte b) { + if (a > b) return a; + else return b; +} +// return |a-b| +byte checkfunc1(byte a, byte b) { + if (a > b) return a - b; + else return b - a; +} +// return the sum mod 256 +byte checkfunc2(byte a, byte b) { + return ((a + b) % 256); +} +// return the multiplication mod 256 +byte checkfunc3(byte a, byte b) { + return ((a * b) % 256); +} +// return a/b or 0 +byte checkfunc4(byte a, byte b) { + if (b != 0) return (a / b); + else return 0; +} + +char *scan_ascii(FILE *fh, UserStruct *User) { + long ascii_size; + char *ascii_data = NULL; + char *mdhex = NULL; + byte md[RIPEMD160_DIGEST_LENGTH]; + char string[1024]; + char dosnewlines = 0; + int lines = 0; + int oldftell; + + // NOTE: fscanf is notorious for its buffer overflows. This must be + // fixed some day, consider this a proof-of-concept version. + + fscanf(fh, "%1000[^\n]", string); + sscanf(string, "%*s %s %s %lu %d %d %d", + User->email, + User->shopid, + &User->reldate, + &User->keytype, + &User->keylevel, + &User->keyformat); + + if (User->keyformat <= BLENKEYFORMAT) { + if (DEBUG) printf( + "Email:[%s] ShopID:[%s] RelDate:[%lu] KeyType[%d] KeyLevel[%d]\n", + User->email, User->shopid, User->reldate, User->keytype, + User->keylevel); + + // read /n/n + + // check if we're reading dow newlines... + oldftell = ftell(fh); + getc(fh); + if ((ftell(fh) - oldftell) == 2) { + // yes ! + dosnewlines = 1; + } + getc(fh); + + fscanf(fh, "%1000[^\n]", string); + strncpy(User->name, string, sizeof(User->name) - 1); + + if (DEBUG) printf("Name:[%s]\n", User->name); + + getc(fh); + + // 4 lines read uptil now... + lines = 4; + + while (getc(fh) != EOF) { + fscanf(fh, "%1000[^\n]", string); + lines++; + // if (DEBUG) printf("%s\n", string); + if (strcmp(string, BLENKEYSEPERATOR) == 0) { + getc(fh); + break; + } + } + + // fh now points at the start of the datablock + ascii_size = ftell(fh); + + if (dosnewlines) { + // if we were reading on dos + // ftell will also count the ^M 's in the file; substract them + ascii_size -= lines; + } + + ascii_data = malloc((ascii_size+1) * sizeof(char)); + fseek(fh, 0, SEEK_SET); + fread(ascii_data, sizeof(char), ascii_size, fh); + ascii_data[ascii_size] = '\0'; + + if (DEBUG) + printf("asciiblock is %ld bytes long:\n[%s]\n", ascii_size, ascii_data); + + // calculate the hash checksum + RIPEMD160(ascii_data, ascii_size, md); + free(ascii_data); + mdhex = Hexify(md, RIPEMD160_DIGEST_LENGTH); + } + + return(mdhex); +} + +char *ReadHexCryptedData(FILE *fh, int *newlinetracker) { + int HexCryptedDataLength = Hex5ToIntFp(fh, newlinetracker); + int DataType = HexToIntFp(fh, newlinetracker); + char *HexCryptedData = malloc((HexCryptedDataLength+1) * sizeof(char)); + int i; + + if (DataType != 1) { + // printf("Error: unexpected datatype for HexCryptedData\n"); + free(HexCryptedData); + HexCryptedData = 0; + } else { + for (i=0; i<(HexCryptedDataLength/2); i++) { + sprintf(HexCryptedData+2*i, "%02X", ReadHexByteFp(fh, newlinetracker)); + } + } + + return(HexCryptedData); +} + +char *ReadHexCryptedKey(FILE *fh, int *newlinetracker) { + int HexCryptedKeyLength = Hex5ToIntFp(fh, newlinetracker); + int DataType = HexToIntFp(fh, newlinetracker); + char *HexCryptedKey = malloc((HexCryptedKeyLength+1) * sizeof(char)); + int i; + + if (DataType != 2) { + // printf("Error: unexpected datatype for HexCryptedKey\n"); + free(HexCryptedKey); + HexCryptedKey = 0; + } else { + for (i=0; i<(HexCryptedKeyLength/2); i++) { + sprintf(HexCryptedKey+2*i, "%02X", ReadHexByteFp(fh, newlinetracker)); + } + } + + return(HexCryptedKey); +} + +// NOTE: CHANGE THIS INTO A KEY OF OUR OWN +void LoadRSApubKey(RSA *Pub) { + static unsigned char n[] = +"\xD1\x12\x0C\x6A\x34\x0A\xCF\x4C\x6B\x34\xA9\x3C\xDD\x1A\x2A\x68" +"\x34\xE5\xB4\xA2\x08\xE8\x9F\xCE\x76\xEF\x4B\x92\x9B\x99\xB4\x57" +"\x72\x95\x78\x1D\x9E\x21\x1B\xF9\x5C\x1B\x0E\xC9\xD0\x89\x75\x28" +"\x08\x13\x6A\xD8\xA9\xC2\xA4\x31\x91\x53\x5A\xB9\x26\x71\x8C\x05"; + static unsigned char e[] = +"\x01\x00\x01"; +/* + static unsigned char e[] = "\x11"; + static unsigned char n[] = +"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F" +"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5" +"\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93" +"\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1" +"\xF5"; +*/ + + Pub->e = BN_bin2bn(e, sizeof(e)-1, Pub->e); + Pub->n = BN_bin2bn(n, sizeof(n)-1, Pub->n); +} + +byte *RSADecryptKey(char *HexCryptedKey) { + byte *CryptedKey = NULL; + byte *Key = NULL; + int KeyLen; + int CryptedKeyLen = strlen(HexCryptedKey)/2; + RSA *Pub = NULL; + + // Load RSA public key + Pub = RSA_new(); + if (Pub == NULL) { + // printf("Error in RSA_new\n"); + } else { + LoadRSApubKey(Pub); + + Key = malloc(RSA_size(Pub) * sizeof(byte)); + + CryptedKey = DeHexify(HexCryptedKey); + + KeyLen = RSA_public_decrypt(CryptedKeyLen, CryptedKey, Key, Pub, + RSA_PKCS1_PADDING); + if (DEBUG) + printf("CryptedKeyLen = %d, KeyLen = %d\n", CryptedKeyLen, KeyLen); + if (KeyLen == -1) { +#ifndef NDEBUG + printf("Error in RSA_public_decrypt: %s\n", ERR_error_string(ERR_get_error(), NULL)); +#endif + free(Key); + Key = NULL; + } + } + + return (Key); +} + +char *DeCryptDatablock(byte *CryptKey, int keylen, char *HexCryptedData) { + RC4_KEY key; + byte *CryptedData = DeHexify(HexCryptedData); + unsigned int datalen = strlen(HexCryptedData)/2; + char *KeyDataString = malloc(datalen * sizeof(char)); + + RC4_set_key(&key, keylen, CryptKey); + RC4(&key, datalen, CryptedData, KeyDataString); + free(CryptedData); + + return(KeyDataString); +} + +char *get_from_datablock(char **DataPtr, char *TypeString) { + int tstringsize = Hex5ToIntCp(DataPtr); + int tstringtype = HexToIntCp(DataPtr); + char *HexString = NULL; + + if (atoi(TypeString) != tstringtype) { + // printf("Unexpected type %d, expected %s\n", tstringtype, TypeString); + } else { + HexString = malloc((tstringsize+1) * sizeof(char)); + + strncpy(HexString, *DataPtr, tstringsize); + *DataPtr += tstringsize; + HexString[tstringsize] = '\0'; + } + + return(HexString); +} + +int ReadKeyFile(char *filename, UserStruct *User, + char **Priv, char **Pub, byte **Byte, char **Python) { + FILE *rawkeyfile; + char *HexAsciiHash = NULL, *HexCryptedData = NULL, *HexCryptedKey = + NULL; + int newlinetracker = 0; // line position, counts from 0-71 + byte *CryptKey = NULL; + char *KeyDataString = NULL; + char *KeyDataPtr = NULL; + char *HexByte = NULL; + char *mdhex = NULL; + int ret_val = 1; + + if ((rawkeyfile = fopen(filename, "rb")) == NULL) { + // printf("error, cannot read %s\n", filename); + } else { + // Scan and interpret the ASCII part + HexAsciiHash = scan_ascii(rawkeyfile, User); + if (DEBUG) printf("\nHexHash: %s\n", HexAsciiHash); + + // Read the HexCryptedData + HexCryptedData = ReadHexCryptedData(rawkeyfile, &newlinetracker); + if (DEBUG) printf("\nHexCryptedData: %s\n", HexCryptedData); + + // Read the HexCryptedKey + HexCryptedKey = ReadHexCryptedKey(rawkeyfile, &newlinetracker); + if (DEBUG) printf("\nHexCryptedKey: %s\n", HexCryptedKey); + + // close keyfile + fclose(rawkeyfile); + + if (HexAsciiHash && HexCryptedKey && HexCryptedData) { + // Decrypt HexCryptedKey + CryptKey = RSADecryptKey(HexCryptedKey); + + if (CryptKey) { + // Decrypt HexCryptedData + KeyDataString = DeCryptDatablock(CryptKey, 16, HexCryptedData); + free(CryptKey); + CryptKey = NULL; + + if (KeyDataString) { + if (DEBUG) printf("\nKeyDataString: %s\n", KeyDataString); + + // Extract data from KeyDataString + KeyDataPtr = KeyDataString; + mdhex = get_from_datablock(&KeyDataPtr, "01"); + *Priv = get_from_datablock(&KeyDataPtr, "02"); + *Pub = get_from_datablock(&KeyDataPtr, "03"); + HexByte = get_from_datablock(&KeyDataPtr, "04"); + if (HexByte) { + *Byte = DeHexify(HexByte); + free(HexByte); + HexByte = NULL; + + *Python = get_from_datablock(&KeyDataPtr, "05"); + + // Check ascii hash + if (strcmp(mdhex, HexAsciiHash) != 0) { + // printf("Ascii part checksums do not match !\n"); + // printf("found: %s\n", mdhex); + // printf("check: %s\n", HexAsciiHash); + ret_val = 2; + } else { + if (DEBUG) printf("\nThe ascii part checksum matches\n"); + // everything ok ! + ret_val = 0; + } + free(mdhex); + mdhex = NULL; + } + + free(KeyDataString); + KeyDataString = NULL; + } + } + } + + // cleanup + + if (HexAsciiHash) { + free(HexAsciiHash); + HexAsciiHash = NULL; + } + + if (HexCryptedKey) { + free(HexCryptedKey); + HexCryptedKey = NULL; + } + + if (HexCryptedData) { + free(HexCryptedData); + HexCryptedData = NULL; + } + } + + return (ret_val); +} + diff --git a/intern/keymaker/key.h b/intern/keymaker/key.h new file mode 100644 index 00000000000..dd84f55f129 --- /dev/null +++ b/intern/keymaker/key.h @@ -0,0 +1,83 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/** + + * $Id$ + * Copyright (C) 2001 NaN Technologies B.V. + * Blender Key loader library external interface + */ + +#ifndef BLENKEY_H +#define BLENKEY_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char byte; + +typedef struct UserStructType { + char name[100]; + char email[100]; + char shopid[100]; + unsigned long reldate; + int keytype; // 1 = Individual, 2 = Corporate, 3 = Unlimited + int keylevel; // key disclosure level, starts at 1 + int keyformat; // if we change the keyformat, up BLENKEYFORMAT +} UserStruct; + +char *Hexify(byte *in, unsigned int length); +byte *DeHexify(char *in); + +byte checkfunc0(byte a, byte b); +byte checkfunc1(byte a, byte b); +byte checkfunc2(byte a, byte b); +byte checkfunc3(byte a, byte b); +byte checkfunc4(byte a, byte b); + +// the byte size of the checksum datablock +// #define MAXBYTEDATABLOCK 1000 + +#define BLENKEYMAGIC "0ce0ba52" +#define BLENKEYSEPERATOR "---+++---" +#define BLENKEYFORMAT 1 + + +int ReadKeyFile(char *filename, UserStruct *User, + char **Priv, char **Pub, byte **Byte, char **Python); + +#ifdef __cplusplus +} +#endif + +#endif /* BLENKEY_H */ + diff --git a/intern/keymaker/key_internal.h b/intern/keymaker/key_internal.h new file mode 100644 index 00000000000..3fa0274c33e --- /dev/null +++ b/intern/keymaker/key_internal.h @@ -0,0 +1,89 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +// ex:ts=4 + +/** + * $Id$ + * Copyright (C) 2001 NaN Technologies B.V. + * Blender Key loader library internal stuff + */ + +#include "openssl/rand.h" +#include "openssl/rsa.h" +#include "openssl/ripemd.h" +#include "openssl/rc4.h" +#include "openssl/err.h" + +#include "mt19937int.h" // Mersenne Twister (under artistic license) + +#define MAXASCIIBLOCK 1000 +#define MAXBYTEDATABLOCK 1000 + +#ifdef NDEBUG + #define DEBUG 0 +#else + #define DEBUG 1 +#endif + +// keyloader and keymaker internal prototypes +int from_hex(char c); +byte ReadHexByteFp(FILE *fh, int *newlinetracker); +byte ReadHexByteCp(char **from); +int HexToInt(int a); +int HexToIntFp(FILE *fh, int *newlinetracker); +int HexToIntCp(char **from); +int Hex5ToInt(byte a, byte b, byte c, byte d, byte e); +int Hex5ToIntFp(FILE *fh, int *newlinetracker); +int Hex5ToIntCp(char **from); +int main(int argc, char **argv); + +// keyloader only internal prototypes +char *scan_ascii(FILE *fh, UserStruct *User); +char *ReadHexCryptedData(FILE *fh, int *newlinetracker); +char *ReadHexCryptedKey(FILE *fh, int *newlinetracker); +void LoadRSApubKey(RSA *Pub); +byte *RSADecryptKey(char *HexCryptedKey); +char *DeCryptDatablock(byte *CryptKey, int keylen, char *HexCryptedData); +char *get_from_datablock(char **DataPtr, char *TypeString); +int Check_All_Byte_Calculus_Data(char *KeyBytePtr); + +// keymaker only internal prototypes +void usage(void); +char *Create_Ascii_Part(int argc, char **argv); +void Create_User_RSA_Keys(unsigned int keylength, + char **rsaPrivString, char **rsaPubString); +char *Create_Byte_Calculus_Data(void); +byte *CreateCryptKey(unsigned int size); +char *CryptDatablock(byte *CryptKey, int keylen, char *KeyDataString); +char *RSACryptKey(RSA *rsa, byte *CryptKey, int KeyLen); +void add_to_datablock(char **DataString, char *HexString, char *TypeString); +void LoadRSAprivKey(RSA *Priv); diff --git a/intern/keymaker/keyloader.c b/intern/keymaker/keyloader.c new file mode 100644 index 00000000000..e4cf61fc3b7 --- /dev/null +++ b/intern/keymaker/keyloader.c @@ -0,0 +1,315 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +// ex:ts=4 + +/** + * $Id$ + * Copyright (C) 2001 NaN Technologies B.V. + * Blender Key Read-tester + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "key_pyc.h" // the Python byte code +#include "key.h" // the external interface +#include "key_internal.h" + +#define TESTReadKeyFile 1 + +int Check_All_Byte_Calculus_Data(char *KeyBytePtr) { + int i; + + // create some unique number arrays + int NoRealRandomArray[MAXBYTEDATABLOCK]; + + typedef byte (*funcpoin)(byte, byte); + funcpoin checkfunc[] = {&checkfunc0, &checkfunc1, &checkfunc2, + &checkfunc3, &checkfunc4}; + + byte *KeyByteData = DeHexify(KeyBytePtr); + + // first create a fixed seed random number generator + sgenrand(666); // seed it fixed + + // initialize arrays with unique numbers + for (i=0; i<MAXBYTEDATABLOCK; i++) { + NoRealRandomArray[i] = i; + } + // then stir the unique number lists + for (i=0; i<MAXBYTEDATABLOCK; i++) { + unsigned long randswap = genrand(); + int swap1 = (int) (randswap % MAXBYTEDATABLOCK); + int swap2 = (int) ((randswap>>16) % MAXBYTEDATABLOCK); + int store = NoRealRandomArray[swap1]; + //printf("%lu %d %d\n", randswap, swap1, swap2); + NoRealRandomArray[swap1] = NoRealRandomArray[swap2]; + NoRealRandomArray[swap2] = store; + } + if (DEBUG) { + printf("\nFixed seed unique number random data: "); + for (i=0; i<MAXBYTEDATABLOCK; i++) { + printf("%d ", NoRealRandomArray[i]); + } + printf("\n\n"); + } + + // check our byte calculus functions on the random data + for (i=0; i<(MAXBYTEDATABLOCK-3); i+=3) { + if (DEBUG) { + char *Pcheckfunc[] = {"max", " - ", " + ", " * ", " / "}; + printf("[%3d]=[%3d]%s[%3d] ", + NoRealRandomArray[i], NoRealRandomArray[i+1], + Pcheckfunc[NoRealRandomArray[i]%5], NoRealRandomArray[i+2]); + printf("%3d%s%3d: %3d == %3d\n", + KeyByteData[NoRealRandomArray[i+1]], + Pcheckfunc[NoRealRandomArray[i]%5], + KeyByteData[NoRealRandomArray[i+2]], + KeyByteData[NoRealRandomArray[i]], + checkfunc[(NoRealRandomArray[i]%5)]( + KeyByteData[NoRealRandomArray[i+1]], + KeyByteData[NoRealRandomArray[i+2]])); + } + if (KeyByteData[NoRealRandomArray[i]] != + checkfunc[(NoRealRandomArray[i]%5)]( + KeyByteData[NoRealRandomArray[i+1]], + KeyByteData[NoRealRandomArray[i+2]])) { + printf("\nByte Checksum failed !\n"); + return (1); + } + } + return (0); +} + +void pub_priv_test(char *HexPriv, char *HexPub) +{ + RSA *rsa = NULL; + // static unsigned char rsa_e[] = "\x11"; + static unsigned char rsa_e[] = "\x01\x00\x01"; + byte cryptKey[16]; + byte *cryptedKey; + byte *pubKey, *privKey; + int pubKeyLen, privKeyLen; + int deCryptKeyLen; + unsigned char *deCryptKey; + int cryptKeyLen = 16; + int cryptedKeyLen; + + strcpy(cryptKey, "abcdefghijklmno"); + + pubKey = DeHexify(HexPub); + pubKeyLen = strlen(HexPub) / 2; + + privKey = DeHexify(HexPriv); + privKeyLen = strlen(HexPriv) / 2; + + rsa = RSA_new(); + if (rsa == NULL) { + fprintf(stderr, "Error in RSA_new\n"); + exit(1); + } + rsa->e = BN_bin2bn(rsa_e, sizeof(rsa_e)-1, rsa->e); + rsa->n = BN_bin2bn(pubKey, pubKeyLen, rsa->n); + rsa->d = BN_bin2bn(privKey, privKeyLen, rsa->d); + + fprintf(stderr, "NOTE e %d, n %d, d %d rsa_size %d\n", + sizeof(rsa_e)-1, pubKeyLen, privKeyLen, RSA_size(rsa)); + + cryptedKey = malloc(RSA_size(rsa) * sizeof(byte)); + cryptedKeyLen = RSA_private_encrypt(cryptKeyLen, cryptKey, + cryptedKey, rsa, RSA_PKCS1_PADDING); + + deCryptKey = malloc(RSA_size(rsa) * sizeof(unsigned char)); + deCryptKeyLen = RSA_public_decrypt(cryptedKeyLen, cryptedKey, + deCryptKey, rsa, RSA_PKCS1_PADDING); + if (deCryptKeyLen == -1) { + printf("Error in RSA_public_decrypt: %s\n", + ERR_error_string(ERR_get_error(), NULL)); + exit(1); + } else { + printf("RSA_public_decrypt test SUCCEEDED\n"); + } + +} + +#ifdef TESTReadKeyFile +int main(int argc, char **argv) { + int result; + UserStruct User; + char *HexPriv = NULL, *HexPub = NULL, *HexPython = NULL; + byte *Byte = NULL; + byte *PythonData = NULL; + int PythonLength; + char *HexByte = NULL; + + if (argc != 2) { + printf("usage: %s keyfile\n", argv[0]); + exit(1); + } + + result = ReadKeyFile(argv[1], &User, &HexPriv, &HexPub, &Byte, &HexPython); + if (result != 0) { + printf("\nReadKeyFile error %d\n", result); + exit(result); + } else { + printf("\nReadKeyFile OK\n"); + } + + // just print the rsaPrivString and rsaPubString + if (DEBUG) printf("\nrsaPrivString: %s\n", HexPriv); + if (DEBUG) printf("\nrsaPubString: %s\n", HexPub); + + // try to private encrypt-public decrypt something + if (DEBUG) pub_priv_test(HexPriv, HexPub); + + // check all the Byte checksums + // rehexify it for our Check_All_Byte_Calculus_Data function ... + HexByte = Hexify(Byte, 1000); + if (Check_All_Byte_Calculus_Data(HexByte) != 0) { + printf("\nByte_Calculus_Data checksums do not match !\n"); + exit(1); + } else { + if (DEBUG) printf("\nThe Byte Calculus Data checksums match\n"); + } + + // Check the KeyPythonPtr + PythonLength = strlen(HexPython)/2; + PythonData = DeHexify(HexPython); + if (memcmp(PythonData, g_keycode, PythonLength) != 0) { + printf("\nPython Byte code datablocks do not match !\n"); + exit(1); + } else { + if (DEBUG) printf("\nThe Python Byte code datablock matches\n"); + } + + return(0); +} +#else +int main(int argc, char **argv) { + FILE *rawkeyfile; + char *AsciiHash; + char *HexCryptedData, *HexCryptedKey; + int newlinetracker = 0; // line position, counts from 0-71 + byte *CryptKey; + char *KeyDataString; + char *KeyDataPtr; + char *mdhex; + char *rsaPrivString; + char *rsaPubString; + char *KeyBytePtr; + char *KeyPythonPtr; + byte *PythonData; + int PythonLength; + UserStruct User; + + if (argc != 2) { + printf("usage: %s keyfile\n", argv[0]); + exit(1); + } + + // open keyfile for reading + if ((rawkeyfile = fopen(argv[1], "r")) == NULL) { + printf("error, cannot read %s\n", argv[1]); + exit(1); + } + + // Scan and interpret the ASCII part + AsciiHash = scan_ascii(rawkeyfile, &User); + if (DEBUG) printf("\nHexHash: %s\n", AsciiHash); + + // Read the HexCryptedData + HexCryptedData = ReadHexCryptedData(rawkeyfile, &newlinetracker); + if (DEBUG) printf("\nHexCryptedData: %s\n", HexCryptedData); + + // Read the HexCryptedKey + HexCryptedKey = ReadHexCryptedKey(rawkeyfile, &newlinetracker); + if (DEBUG) printf("\nHexCryptedKey: %s\n", HexCryptedKey); + + // close keyfile + fclose(rawkeyfile); + + // Decrypt HexCryptedKey + CryptKey = RSADecryptKey(HexCryptedKey); + + // Decrypt HexCryptedData + KeyDataString = DeCryptDatablock(CryptKey, 16, HexCryptedData); + free(CryptKey); + free(HexCryptedData); + free(HexCryptedKey); + if (DEBUG) printf("\nKeyDataString: %s\n", KeyDataString); + + // Extract data from KeyDataString + KeyDataPtr = KeyDataString; + + mdhex = get_from_datablock(&KeyDataPtr, "01"); + rsaPrivString = get_from_datablock(&KeyDataPtr, "02"); + rsaPubString = get_from_datablock(&KeyDataPtr, "03"); + KeyBytePtr = get_from_datablock(&KeyDataPtr, "04"); + KeyPythonPtr = get_from_datablock(&KeyDataPtr, "05"); + free(KeyDataString); + + // Check ascii hash + if (strcmp(mdhex, AsciiHash) != 0) { + printf("Ascii part checksums do not match !\n"); + printf("found: %s\n", mdhex); + printf("check: %s\n", AsciiHash); + exit(1); + } else { + if (DEBUG) printf("\nThe ascii part checksum matches\n"); + } + + // just print the rsaPrivString and rsaPubString + if (DEBUG) printf("\nrsaPrivString: %s\n", rsaPrivString); + if (DEBUG) printf("\nrsaPubString: %s\n", rsaPubString); + + // check all the Byte checksums + if (Check_All_Byte_Calculus_Data(KeyBytePtr) != 0) { + printf("Byte_Calculus_Data checksums do not match !\n"); + exit(1); + } else { + if (DEBUG) printf("\nThe Byte Calculus Data checksums match\n"); + } + + // Check the KeyPythonPtr + PythonLength = strlen(KeyPythonPtr)/2; + PythonData = DeHexify(KeyPythonPtr); + if (memcmp(PythonData, g_keycode, PythonLength) != 0) { + printf("Python Byte code datablocks do not match !\n"); + exit(1); + } else { + if (DEBUG) printf("\nThe Python Byte code datablock matches\n"); + } + + return(0); +} +#endif diff --git a/intern/keymaker/mt19937int.c b/intern/keymaker/mt19937int.c new file mode 100644 index 00000000000..7845f9ad56e --- /dev/null +++ b/intern/keymaker/mt19937int.c @@ -0,0 +1,130 @@ +/* A C-program for MT19937: Integer version (1999/10/28) */ + +/* genrand() generates one pseudorandom unsigned integer (32bit) */ +/* which is uniformly distributed among 0 to 2^32-1 for each */ +/* call. sgenrand(seed) sets initial values to the working area */ +/* of 624 words. Before genrand(), sgenrand(seed) must be */ +/* called once. (seed is any 32-bit integer.) */ +/* Coded by Takuji Nishimura, considering the suggestions by */ +/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */ + +/* This library is free software under the Artistic license: */ +/* see the file COPYING distributed together with this code. */ +/* For the verification of the code, its output sequence file */ +/* mt19937int.out is attached (2001/4/2) */ + +/* Copyright (C) 1997, 1999 Makoto Matsumoto and Takuji Nishimura. */ +/* Any feedback is very welcome. For any question, comments, */ +/* see http://www.math.keio.ac.jp/matumoto/emt.html or email */ +/* matumoto@math.keio.ac.jp */ + +/* REFERENCE */ +/* M. Matsumoto and T. Nishimura, */ +/* "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform */ +/* Pseudo-Random Number Generator", */ +/* ACM Transactions on Modeling and Computer Simulation, */ +/* Vol. 8, No. 1, January 1998, pp 3--30. */ + +#include<stdio.h> + +#include "mt19937int.h" + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0df /* constant vector a */ +#define UPPER_MASK 0x80000000 /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffff /* least significant r bits */ + +/* Tempering parameters */ +#define TEMPERING_MASK_B 0x9d2c5680 +#define TEMPERING_MASK_C 0xefc60000 +#define TEMPERING_SHIFT_U(y) (y >> 11) +#define TEMPERING_SHIFT_S(y) (y << 7) +#define TEMPERING_SHIFT_T(y) (y << 15) +#define TEMPERING_SHIFT_L(y) (y >> 18) + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* Initializing the array with a seed */ +void sgenrand(signed long seed) +{ + int i; + + for (i=0;i<N;i++) { + mt[i] = seed & 0xffff0000; + seed = 69069 * seed + 1; + mt[i] |= (seed & 0xffff0000) >> 16; + seed = 69069 * seed + 1; + } + mti = N; +} + +/* Initialization by "sgenrand()" is an example. Theoretically, */ +/* there are 2^19937-1 possible states as an intial state. */ +/* This function allows to choose any of 2^19937-1 ones. */ +/* Essential bits in "seed_array[]" is following 19937 bits: */ +/* (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1]. */ +/* (seed_array[0]&LOWER_MASK) is discarded. */ +/* Theoretically, */ +/* (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1] */ +/* can take any values except all zeros. */ +void lsgenrand(unsigned long *seed_array) + /* the length of seed_array[] must be at least N */ +{ + int i; + + for (i=0;i<N;i++) + mt[i] = seed_array[i]; + mti=N; +} + +unsigned long genrand() +{ + unsigned long y; + static unsigned long mag01[2]={0x0, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if sgenrand() has not been called, */ + sgenrand(4357); /* a default initial seed is used */ + + for (kk=0;kk<N-M;kk++) { + y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); + mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1]; + } + for (;kk<N-1;kk++) { + y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); + mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; + + mti = 0; + } + + y = mt[mti++]; + y ^= TEMPERING_SHIFT_U(y); + y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; + y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; + y ^= TEMPERING_SHIFT_L(y); + + return y; +} + +/* This main() outputs first 1000 generated numbers. */ +/* +main() +{ + int i; + + sgenrand(4357); + for (i=0; i<1000; i++) { + printf("%10lu ", genrand()); + if (i%5==4) printf("\n"); + } +} +*/ diff --git a/intern/keymaker/mt19937int.h b/intern/keymaker/mt19937int.h new file mode 100644 index 00000000000..49acdd7ba4c --- /dev/null +++ b/intern/keymaker/mt19937int.h @@ -0,0 +1,45 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +// ex:ts=4 + +/** + * $Id$ + * Copyright (C) 2001 NaN Technologies B.V. + * Mersenne Twister prototypes + */ + +// external: +void sgenrand(signed long seed); +unsigned long genrand(void); + +// internal: +void lsgenrand(unsigned long *seed_array); diff --git a/intern/keymaker/python/key_pyc.h b/intern/keymaker/python/key_pyc.h new file mode 100644 index 00000000000..75e35832a21 --- /dev/null +++ b/intern/keymaker/python/key_pyc.h @@ -0,0 +1,153 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/* generated by keygen.py -- don't edit !! */ + + +#define KEYCODELEN 1157 +static unsigned char g_keycode[] = { + 0x63,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x73, + 0xb3,0x00,0x00,0x00,0x7f,0x00,0x00,0x7f,0x02,0x00, + 0x64,0x00,0x00,0x6b,0x00,0x00,0x5a,0x00,0x00,0x7f, + 0x06,0x00,0x64,0x01,0x00,0x84,0x00,0x00,0x5a,0x01, + 0x00,0x7f,0x09,0x00,0x64,0x02,0x00,0x84,0x00,0x00, + 0x5a,0x02,0x00,0x7f,0x11,0x00,0x64,0x03,0x00,0x84, + 0x00,0x00,0x5a,0x03,0x00,0x7f,0x1c,0x00,0x65,0x00, + 0x00,0x69,0x04,0x00,0x83,0x00,0x00,0x5a,0x05,0x00, + 0x7f,0x1d,0x00,0x7f,0x21,0x00,0x65,0x00,0x00,0x69, + 0x06,0x00,0x83,0x00,0x00,0x5a,0x07,0x00,0x7f,0x22, + 0x00,0x65,0x08,0x00,0x65,0x07,0x00,0x83,0x01,0x00, + 0x5a,0x09,0x00,0x7f,0x23,0x00,0x65,0x03,0x00,0x65, + 0x09,0x00,0x83,0x01,0x00,0x01,0x7f,0x24,0x00,0x78, + 0x39,0x00,0x65,0x0a,0x00,0x65,0x07,0x00,0x83,0x01, + 0x00,0x64,0x04,0x00,0x7f,0x24,0x00,0x72,0x26,0x00, + 0x5a,0x0b,0x00,0x7f,0x25,0x00,0x65,0x00,0x00,0x69, + 0x0c,0x00,0x65,0x09,0x00,0x65,0x0b,0x00,0x19,0x65, + 0x00,0x00,0x69,0x0d,0x00,0x65,0x0b,0x00,0x83,0x01, + 0x00,0x83,0x02,0x00,0x01,0x71,0x82,0x00,0x57,0x64, + 0x00,0x00,0x53,0x28,0x05,0x00,0x00,0x00,0x4e,0x63, + 0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x73,0x1c, + 0x00,0x00,0x00,0x7f,0x06,0x00,0x7f,0x07,0x00,0x7f, + 0x08,0x00,0x7c,0x00,0x00,0x7c,0x01,0x00,0x7c,0x02, + 0x00,0x66,0x03,0x00,0x61,0x03,0x00,0x64,0x00,0x00, + 0x53,0x28,0x01,0x00,0x00,0x00,0x4e,0x28,0x04,0x00, + 0x00,0x00,0x73,0x01,0x00,0x00,0x00,0x61,0x73,0x01, + 0x00,0x00,0x00,0x62,0x73,0x01,0x00,0x00,0x00,0x63, + 0x73,0x05,0x00,0x00,0x00,0x5f,0x73,0x65,0x65,0x64, + 0x28,0x03,0x00,0x00,0x00,0x73,0x01,0x00,0x00,0x00, + 0x61,0x73,0x01,0x00,0x00,0x00,0x62,0x73,0x01,0x00, + 0x00,0x00,0x63,0x73,0x08,0x00,0x00,0x00,0x3c,0x73, + 0x74,0x72,0x69,0x6e,0x67,0x3e,0x73,0x04,0x00,0x00, + 0x00,0x73,0x65,0x65,0x64,0x06,0x00,0x73,0x04,0x00, + 0x00,0x00,0x03,0x01,0x03,0x01,0x63,0x00,0x00,0x03, + 0x00,0x03,0x00,0x03,0x00,0x73,0x70,0x00,0x00,0x00, + 0x7f,0x09,0x00,0x7f,0x0a,0x00,0x7f,0x0b,0x00,0x74, + 0x00,0x00,0x5c,0x03,0x00,0x7d,0x00,0x00,0x7d,0x01, + 0x00,0x7d,0x02,0x00,0x7f,0x0c,0x00,0x64,0x01,0x00, + 0x7c,0x00,0x00,0x14,0x64,0x02,0x00,0x16,0x7d,0x00, + 0x00,0x7f,0x0d,0x00,0x64,0x03,0x00,0x7c,0x01,0x00, + 0x14,0x64,0x04,0x00,0x16,0x7d,0x01,0x00,0x7f,0x0e, + 0x00,0x64,0x05,0x00,0x7c,0x02,0x00,0x14,0x64,0x06, + 0x00,0x16,0x7d,0x02,0x00,0x7f,0x0f,0x00,0x7c,0x00, + 0x00,0x7c,0x01,0x00,0x7c,0x02,0x00,0x66,0x03,0x00, + 0x61,0x00,0x00,0x7f,0x10,0x00,0x7c,0x00,0x00,0x7c, + 0x01,0x00,0x17,0x7c,0x02,0x00,0x17,0x53,0x64,0x00, + 0x00,0x53,0x28,0x07,0x00,0x00,0x00,0x4e,0x69,0xab, + 0x00,0x00,0x00,0x69,0x3d,0x76,0x00,0x00,0x69,0xac, + 0x00,0x00,0x00,0x69,0x63,0x76,0x00,0x00,0x69,0xaa, + 0x00,0x00,0x00,0x69,0x73,0x76,0x00,0x00,0x28,0x04, + 0x00,0x00,0x00,0x73,0x05,0x00,0x00,0x00,0x5f,0x73, + 0x65,0x65,0x64,0x73,0x01,0x00,0x00,0x00,0x61,0x73, + 0x01,0x00,0x00,0x00,0x62,0x73,0x01,0x00,0x00,0x00, + 0x63,0x28,0x03,0x00,0x00,0x00,0x73,0x01,0x00,0x00, + 0x00,0x61,0x73,0x01,0x00,0x00,0x00,0x62,0x73,0x01, + 0x00,0x00,0x00,0x63,0x73,0x08,0x00,0x00,0x00,0x3c, + 0x73,0x74,0x72,0x69,0x6e,0x67,0x3e,0x73,0x09,0x00, + 0x00,0x00,0x72,0x61,0x6e,0x64,0x6f,0x6d,0x69,0x7a, + 0x65,0x09,0x00,0x73,0x0e,0x00,0x00,0x00,0x03,0x01, + 0x03,0x01,0x12,0x01,0x11,0x01,0x11,0x01,0x11,0x01, + 0x12,0x01,0x63,0x01,0x00,0x06,0x00,0x06,0x00,0x03, + 0x00,0x73,0x8b,0x00,0x00,0x00,0x7f,0x11,0x00,0x7f, + 0x13,0x00,0x74,0x00,0x00,0x7c,0x00,0x00,0x83,0x01, + 0x00,0x7d,0x01,0x00,0x7f,0x14,0x00,0x78,0x6f,0x00, + 0x74,0x03,0x00,0x7c,0x01,0x00,0x83,0x01,0x00,0x64, + 0x01,0x00,0x7f,0x14,0x00,0x72,0x5c,0x00,0x7d,0x02, + 0x00,0x7f,0x15,0x00,0x7c,0x01,0x00,0x7c,0x02,0x00, + 0x18,0x7d,0x03,0x00,0x7f,0x16,0x00,0x74,0x06,0x00, + 0x74,0x07,0x00,0x83,0x00,0x00,0x7c,0x03,0x00,0x16, + 0x83,0x01,0x00,0x7d,0x04,0x00,0x7f,0x17,0x00,0x7c, + 0x00,0x00,0x7c,0x02,0x00,0x19,0x7d,0x05,0x00,0x7f, + 0x18,0x00,0x7c,0x00,0x00,0x7c,0x02,0x00,0x7c,0x04, + 0x00,0x17,0x19,0x7c,0x00,0x00,0x7c,0x02,0x00,0x3c, + 0x7f,0x19,0x00,0x7c,0x05,0x00,0x7c,0x00,0x00,0x7c, + 0x02,0x00,0x7c,0x04,0x00,0x17,0x3c,0x71,0x24,0x00, + 0x57,0x64,0x00,0x00,0x53,0x28,0x02,0x00,0x00,0x00, + 0x4e,0x69,0x00,0x00,0x00,0x00,0x28,0x0a,0x00,0x00, + 0x00,0x73,0x03,0x00,0x00,0x00,0x6c,0x65,0x6e,0x73, + 0x04,0x00,0x00,0x00,0x6c,0x69,0x73,0x74,0x73,0x04, + 0x00,0x00,0x00,0x73,0x69,0x7a,0x65,0x73,0x06,0x00, + 0x00,0x00,0x78,0x72,0x61,0x6e,0x67,0x65,0x73,0x01, + 0x00,0x00,0x00,0x69,0x73,0x04,0x00,0x00,0x00,0x6c, + 0x65,0x66,0x74,0x73,0x03,0x00,0x00,0x00,0x69,0x6e, + 0x74,0x73,0x09,0x00,0x00,0x00,0x72,0x61,0x6e,0x64, + 0x6f,0x6d,0x69,0x7a,0x65,0x73,0x01,0x00,0x00,0x00, + 0x72,0x73,0x03,0x00,0x00,0x00,0x74,0x6d,0x70,0x28, + 0x06,0x00,0x00,0x00,0x73,0x04,0x00,0x00,0x00,0x6c, + 0x69,0x73,0x74,0x73,0x04,0x00,0x00,0x00,0x73,0x69, + 0x7a,0x65,0x73,0x01,0x00,0x00,0x00,0x69,0x73,0x04, + 0x00,0x00,0x00,0x6c,0x65,0x66,0x74,0x73,0x01,0x00, + 0x00,0x00,0x72,0x73,0x03,0x00,0x00,0x00,0x74,0x6d, + 0x70,0x73,0x08,0x00,0x00,0x00,0x3c,0x73,0x74,0x72, + 0x69,0x6e,0x67,0x3e,0x73,0x04,0x00,0x00,0x00,0x73, + 0x74,0x69,0x72,0x11,0x00,0x73,0x10,0x00,0x00,0x00, + 0x03,0x02,0x0f,0x01,0x12,0x00,0x09,0x01,0x0d,0x01, + 0x16,0x01,0x0d,0x01,0x15,0x01,0x69,0x00,0x00,0x00, + 0x00,0x28,0x0e,0x00,0x00,0x00,0x73,0x04,0x00,0x00, + 0x00,0x70,0x72,0x6f,0x74,0x73,0x04,0x00,0x00,0x00, + 0x73,0x65,0x65,0x64,0x73,0x09,0x00,0x00,0x00,0x72, + 0x61,0x6e,0x64,0x6f,0x6d,0x69,0x7a,0x65,0x73,0x04, + 0x00,0x00,0x00,0x73,0x74,0x69,0x72,0x73,0x07,0x00, + 0x00,0x00,0x67,0x65,0x74,0x73,0x65,0x65,0x64,0x73, + 0x05,0x00,0x00,0x00,0x5f,0x73,0x65,0x65,0x64,0x73, + 0x06,0x00,0x00,0x00,0x67,0x65,0x74,0x6c,0x65,0x6e, + 0x73,0x01,0x00,0x00,0x00,0x6e,0x73,0x05,0x00,0x00, + 0x00,0x72,0x61,0x6e,0x67,0x65,0x73,0x04,0x00,0x00, + 0x00,0x6c,0x69,0x73,0x74,0x73,0x06,0x00,0x00,0x00, + 0x78,0x72,0x61,0x6e,0x67,0x65,0x73,0x01,0x00,0x00, + 0x00,0x69,0x73,0x06,0x00,0x00,0x00,0x73,0x65,0x74, + 0x70,0x74,0x72,0x73,0x06,0x00,0x00,0x00,0x67,0x65, + 0x74,0x70,0x74,0x72,0x28,0x00,0x00,0x00,0x00,0x73, + 0x08,0x00,0x00,0x00,0x3c,0x73,0x74,0x72,0x69,0x6e, + 0x67,0x3e,0x73,0x01,0x00,0x00,0x00,0x3f,0x02,0x00, + 0x73,0x16,0x00,0x00,0x00,0x0f,0x04,0x0c,0x03,0x0c, + 0x08,0x0c,0x0b,0x0f,0x01,0x03,0x04,0x0f,0x01,0x0f, + 0x01,0x0d,0x01,0x12,0x00,0x09,0x01 +};
\ No newline at end of file |