Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit a267d6f869317e6893db0c27a61b6e44622b9ccc @dudochkin-victor committed Nov 23, 2011
0 README
No changes.
17 README.md
@@ -0,0 +1,17 @@
+# nodewm
+*Is a FAST nodejs library for signing WebMoney requests written in C/C++*
+
+## Install:
+1) go to the directory with nodewm library
+
+2) execute `node-waf configure build`
+
+3) get module from `./build/default/wmsigner.node`
+
+## Using nodewm
+
+var wmsigner = require("./build/default/wmsigner");
+
+var sign = wmsigner.sign('Your Wallet', 'Your Password', 'Your Base 64 Encoded KWM file', 'String to sign');
+
+console.log('SIGN: ' + sign);
12 package.json
@@ -0,0 +1,12 @@
+{
+ "name": "nodewm",
+ "author": "Dudochkin Victor",
+ "description": "wmsigner library for node which interact with WebMoney",
+ "version": "1.0.1",
+ "contributors": [
+ { "name": "Dudochkin Victor", "email": "blacksmith@gogoo.ru" }
+ ],
+ "main": "build/default/wmsigner",
+ "directories": { "lib": "./build/default" },
+ "engines": { "node": ">= 0.2.0" }
+}
3 test.js
@@ -0,0 +1,3 @@
+var wmsigner = require("./build/default/wmsigner");
+var sign = wmsigner.sign('<Your Wallet>', 'Your Password', 'Your Base64 encoded KWM file', 'string to sign');
+console.log('SIGN: ' + sign);
2 test.sh
@@ -0,0 +1,2 @@
+wmsigner-2.0.2/wmsigner -w <Your Wallet> -p "Your Password" -K64 "Your Base64 encoded KWM file" -s "string to sign"
+echo ""
185 wmlib.cc
@@ -0,0 +1,185 @@
+/**
+ * FAST nodejs(http://github.com/ry/node/) library for making hashes
+ *
+ * @package wmlib
+ * @link http://github.com/brainfucker/hashlib
+ * @autor Oleg Illarionov <oleg@emby.ru>
+ * @version 1.0
+ */
+
+#include <iostream>
+#include <stdio.h>
+
+#include <v8.h>
+#include <ev.h>
+#include <eio.h>
+#include <fcntl.h>
+
+#include "stdafx.h"
+#include "stdio.h"
+#include "signer.h"
+#include <errno.h>
+#include <stdlib.h>
+#include "base64.h"
+#include "cmdbase.h"
+
+using namespace v8;
+
+void NormStr(char *str);
+
+static char pszOut[MAXBUF + 1] = "";
+
+Handle<Value> sign(const Arguments& args) {
+ HandleScope scope;
+ String::Utf8Value uLogin(args[0]->ToString());
+ String::Utf8Value uPwd(args[1]->ToString());
+ String::Utf8Value uKeyData(args[2]->ToString());
+ String::Utf8Value uSignData(args[3]->ToString());
+
+ szptr szLogin, szPwd, szFileName, szIn, szSign;
+ char szBufforInv[MAXSTR + 1] = "";
+ char szKeyData[MAXBUF + 1] = ""; // Buffer for Signre-s key
+ int ErrorCode = 0;
+ bool result = FALSE;
+
+ char szLoginCL[MAXSTR+1] = "";
+ char szPwdCL[MAXSTR+1] = "";
+ strncpy( szLoginCL, (char*) *uLogin, MAXSTR);
+ strncpy( szPwdCL, (char*) *uPwd, MAXSTR);
+ szLogin = szLoginCL;
+ szPwd = szPwdCL;
+
+ size_t Bytes = 0;
+ char KeyBuffer[512];
+
+ if (strlen((char*) *uKeyData) != 220)
+ return scope.Close(ThrowException(Exception::Error(String::New((char*)"Key string has illegal length!"))));
+ strcpy(szKeyData, (char*) *uKeyData);
+ Bytes = code64(ENCODE, KeyBuffer, 512, szKeyData, 220);
+ if (Bytes != 164)
+ return scope.Close(ThrowException(Exception::Error(String::New((char*)"Bad key string in parameter!"))));
+ memcpy(szKeyData, KeyBuffer, 164);
+
+ if( strlen( (char*) *uSignData )) {
+ strncpy( szBufforInv, (char*) *uSignData, MAXSTR);
+ }
+ NormStr(szBufforInv);
+ szIn = szBufforInv;
+
+ //----------------------------------------------------
+ // sigining (new)
+
+ Signer sign(szLogin, szPwd, szFileName);
+ sign.isIgnoreKeyFile = false;
+ sign.isIgnoreIniFile = true;
+ sign.isKWMFileFromCL = false;
+ sign.Key64Flag = true;
+
+ sign.SetKeyFromCL(TRUE, szKeyData);
+
+ result = sign.Sign(szIn, szSign);
+ ErrorCode = sign.ErrorCode();
+
+ if (result) {
+ strncpy(pszOut, szSign, MAXSTR);
+ //printf("%s", pszOut);
+ return scope.Close(String::New((char*) pszOut));
+ } else {
+ sprintf(pszOut, "WMSigner Error: %d\n", ErrorCode);
+ //printf("%s", pszOut);
+ return scope.Close(ThrowException(Exception::Error(String::New(pszOut))));
+ }
+}
+
+//Handle<Value> md6(const Arguments& args) {
+ // HandleScope scope;
+ //
+ // String::Utf8Value data(args[0]->ToString());
+ //
+ // int len(32);
+ // if (!args[1]->IsUndefined()) {
+ // len=args[1]->ToInteger()->Value();
+ // }
+ // unsigned char digest[len];
+ // unsigned char hexdigest[len];
+ // md6_hash(len*8, (unsigned char*) *data, data.length(), digest);
+ //
+ // int half_len=len/2;
+ // if (len%2!=0) half_len++;
+ //
+ // make_digest_ex(hexdigest, digest, half_len);
+ //
+ // return scope.Close(String::New((char*)hexdigest,len));
+//}
+
+//int read_cb(eio_req *req) {
+ // file_data *fd=(file_data *)req->data;
+ // unsigned char *buf = (unsigned char *)EIO_BUF (req);
+ // int bytes=(int)EIO_RESULT(req);
+ // MD5Update (&fd->mdContext, buf, bytes);
+ // if (bytes==10240) {
+ // // Read next block
+ // fd->byte+=bytes;
+ // eio_read(fd->fd, 0, 10240, fd->byte, EIO_PRI_DEFAULT, read_cb, static_cast<void*>(fd));
+ // } else {
+ // // Final
+ // unsigned char digest[16];
+ // unsigned char hexdigest[32];
+ // MD5Final(digest, &fd->mdContext);
+ // make_digest_ex(hexdigest, digest, 16);
+ //
+ // Persistent<Object> *data = reinterpret_cast<Persistent<Object>*>(fd->environment);
+ //
+ // v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast((*data)->Get(String::New("callback")));
+ // Handle<Object> recv = Handle<Object>::Cast((*data)->Get(String::New("recv")));
+ // v8::Handle<v8::Value> outArgs[] = {String::New((char *)hexdigest,32)};
+ // callback->Call(recv, 1, outArgs);
+ // data->Dispose();
+ // eio_close(fd->fd, 0, 0, (void*)"close");
+ // ev_unref(EV_DEFAULT_UC);
+ // }
+ //
+ // return 0;
+//}
+
+//Handle<Value> get_md5_file_async(char * path, void* data) {
+ // eio_open (path, O_RDONLY, 0777, 0, open_cb, data);
+ // return v8::Boolean::New(true);
+//}
+
+//Handle<Value> md5_file(const Arguments& args) {
+ // HandleScope scope;
+ // struct stat stFileInfo;
+ // String::Utf8Value path(args[0]->ToString());
+ // char* cpath=*path;
+ // int intStat = stat(cpath,&stFileInfo);
+ // if (intStat == 0) {
+ // if (args[1]->IsFunction()) {
+ // v8::Local<v8::Object> arguments = v8::Object::New();
+ // arguments->Set(String::New("path"),args[0]->ToString());
+ // arguments->Set(String::New("callback"),args[1]);
+ // arguments->Set(String::New("recv"),args.This());
+ // Persistent<Object> *data = new Persistent<Object>();
+ // *data = Persistent<Object>::New(arguments);
+ //
+ // file_data *fd=new file_data;
+ // fd->byte = 0;
+ // fd->environment = data;
+ //
+ // MD5Init(&fd->mdContext);
+ // ev_ref(EV_DEFAULT_UC);
+ // return scope.Close(get_md5_file_async(cpath,static_cast<void*>(fd)));
+ // } else {
+ // return scope.Close(get_md5_file(cpath));
+ // }
+ // } else {
+ // std::string s="Cannot read ";
+ // s+=cpath;
+ // return scope.Close(ThrowException(Exception::Error(String::New(s.c_str()))));
+ // }
+//}
+
+extern "C" void init(Handle<Object> target) {
+ HandleScope scope;
+ target->Set(String::New("sign"), FunctionTemplate::New(sign)->GetFunction());
+}
26 wmsigner-2.0.2/COPYING
@@ -0,0 +1,26 @@
+ BSD License
+
+Copyright (c) 2005, WM Transfer Ltd., Belize City, Belize
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+- Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+- Neither the name of the WM Transfer Ltd. nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
55 wmsigner-2.0.2/ChangeLog
@@ -0,0 +1,55 @@
+Changelog
+
+Mon Sep 21 18:33:00 MSK 2009
+----------------------------
+ V 2.0.2
+ * Bug:
+ - ignore parameter in commandline when pass length=1
+
+Thu Aug 14 17:45:00 MSK 2007
+----------------------------
+ V 2.0.1
+ * Bug:
+ - error with signing string with \n
+
+Mon Jul 23 15:08:00 MSK 2007
+----------------------------
+ V 2.0
+ * Bug:
+ - was: unjustified require wmsigner.ini
+
+Wed Jul 18 19:38:00 MSK 2007
+----------------------------
+ V 2.0 beta
+ * Added command line options (see man page)
+ * Big code changes
+ * Rename WMSigner to wmsigner
+
+Tue Jan 9 17:02:00 MSK 2007
+----------------------------
+ V 1.4
+ * Compatibles:
+ - add precompiler directive for compatible FreeBSD <= 4,
+ patch by Kostya Glazyrin <loriecat@rambler.ru>
+
+Mon Nov 14 17:05:00 MSK 2006
+----------------------------
+ V 1.3
+ * Small bug:
+ - fix VERSION in Makefile
+ - fix '\r\n' bug (appear in X6 WebMoney interface)
+ * Remove '-static' compiler directive
+
+Mon Jul 3 14:57:00 MSK 2006
+----------------------------
+ V 1.2
+ * Compatibles:
+ - 64-bit arch compatibles patch by Sergey Skvortsov <skv@protey.ru>
+ - add ChangeLog, README, README.rus in /usr/share/doc/WMSigner
+
+Fri Jun 30 18:27:44 MSK 2006
+----------------------------
+ V 1.1
+ * Bugfixes:
+ - memory leak patch by Sergey Skvortsov <skv@protey.ru>
+
5 wmsigner-2.0.2/INSTALL
@@ -0,0 +1,5 @@
+
+Compile and install wmsigner is easy:
+
+$ make
+$ make install
42 wmsigner-2.0.2/Makefile
@@ -0,0 +1,42 @@
+PACKAGE = wmsigner
+VERSION = 2.0.1
+SHELL = /bin/sh
+
+PREFIX = ${prefix}/usr/local
+bindir = $(PREFIX)/bin
+mandir = $(PREFIX)/man/man1
+docdir = $(prefix)/usr/share/doc/wmsigner
+
+# all dirs
+DIRS = $(bindir) $(mandir) $(docdir)
+
+# INSTALL scripts
+INSTALL = install -p --verbose
+INSTALL_BIN = $(INSTALL) -m 755
+INSTALL_DIR = $(INSTALL) -m 755 -d
+INSTALL_DATA = $(INSTALL) -m 644
+INSTALL_DOC = $(INSTALL) -m 644
+
+all: crypto.cpp md4.cpp rsalib1.cpp cmdbase.cpp signer.cpp wmsigner.cpp base64.cpp code64.cpp
+ /usr/bin/g++ crypto.cpp md4.cpp rsalib1.cpp base64.cpp cmdbase.cpp signer.cpp wmsigner.cpp -o wmsigner
+ /usr/bin/g++ code64.cpp base64.cpp -o code64
+ /bin/chmod g+x,o+x wmsigner code64
+
+test:
+ perl t/runtests
+ rm -f test.b64 wmsigner.ini
+
+install: wmsigner code64
+ for dir in $(DIRS) ; do \
+ $(INSTALL_DIR) $$dir ; \
+ done
+ $(INSTALL_BIN) wmsigner $(bindir)
+ $(INSTALL_BIN) code64 $(bindir)
+ $(INSTALL_DATA) wmsigner.1 $(mandir)
+ $(INSTALL_DOC) INSTALL $(docdir)
+ $(INSTALL_DOC) README $(docdir)
+ $(INSTALL_DOC) README.rus $(docdir)
+ $(INSTALL_DOC) ChangeLog $(docdir)
+
+clean:
+ rm -f wmsigner code64 test.b64 wmsigner.ini
14 wmsigner-2.0.2/README
@@ -0,0 +1,14 @@
+README
+
+See man page wmsigner.1, please.
+
+Also see:
+http://www.wmtransfer.com/
+
+Contact e-mail: unix@wmtransfer.com
+
+The proprietor and administrator is WM Transfer Ltd;
+No. 35 New Road, P.O. Box 1708, Belize City, Belize;
+The management company: DICSA BALTIC International Group of Lawyers
+partner UAB (Kraziu Str. 21, 01108, Vilnius, Lithuania);
+Director: Giedre Petkunaite.
142 wmsigner-2.0.2/README.rus
@@ -0,0 +1,142 @@
+
+*** ВНИМАНИЕ ***
+
+Если Вы используете язык программирования отличный от shell(bash), то имеет смысл
+обратить внимание на библиотеки с поддержкой используемого языка:
+http://wiki.webmoney.ru/wiki/show/WMSigner
+
+****************
+
+
+
+Модуль wmsigner предназначен для генерации подписи произвольной строки.
+Подробнее вы можете узнать об этом на странице
+http://www.webmoney.ru/rus/developers/interfaces/xml/authdescr/wmsigner.shtml
+
+
+
+Для компиляции выполните команду
+ $ make
+в результате чего будет создан модуль wmsigner и модуль code64.
+В случае ошибок компиляции установите требуемые компилятором библиотеки.
+На подавляющем большинстве систем компиляция проходит успешно.
+
+Для win32 модули wmsigner.exe и code64.exe поставляются в скомпилированном виде.
+
+Для тестирования работоспособности нужно положить в каталог компиляции
+файл ключа и создать файл test.ini c 5-ю строчками:
+
+WMID-идентификатор ( пример: 123456789012 )
+пароль к файлу ключей ( my_pass )
+путь к файлу ключей ( ./123456789012.kwm (unix) или 123456789012.kwm (win32) )
+имя исполняемого модуля ( ./wmsigner (unix) или wmsigner.exe (win32) )
+имя исполняемого модуля кодера-декодера ключа( ./code64 (unix) или code64.exe (win32) )
+
+Пример этого файла - прилагается.
+
+и выполнить команду
+ $ make test
+
+Под Windows для тестирования Вам понадобится ActivePerl с модулем Net::SSLeay
+
+ > test_w32.bat
+
+Если все тесты прошли успешно, то можно собранные модули можно использовать.
+
+Для установки его в каталог /usr/local/bin выполните команду
+ $ make install
+Для установки в каталог пользователя просто скопируйте туда файл wmsigner (wmsigner.exe).
+
+Если ваш хостинг-провайдер не предоставляет вам консольного доступа, необходимо
+попросить поддержку хостинга собрать модуль.
+
+Для работы модуля необходимы файлы wmsigner.ini (создается самостоятельно
+пользователем) и файл ключей WebMoney WM-магазина.
+Чаще всего модуль должен располагаться либо в $HOME пользователя, либо в подкаталоге.
+НЕЛЬЗЯ РАСПОЛАГАТЬ МОДУЛЬ ТАМ ЖЕ ГДЕ И СКРИПТЫ, т.к. в этом случае с сайта можно будет
+скачать конфигурационный файл, в котором содержится пароль к файлу ключей.
+Файл wmsigner.ini модуль ищет в том же каталоге где находится сам.
+Необходимо на него поставить право на чтение (wmsigner должен иметь право прочесть его).
+
+Следующий шаг - создание файла wmsigner.ini
+Он описывает ваш WM-идентификатор, и содержит, по строкам :
+wm идентификатор
+пароль к нему
+путь с именем файла ключей
+
+Типичная конфигурация:
+
+Каталог скриптов и html-документов: /home/my_site/html
+Каталог расположения wmsigner: /home/my_site/sign
+Конфигурационный файл: /home/my_site/sign/wmsigner.ini :
+123456789012
+pass
+/home/my_site/sign/keyfile.kwm
+
+При работе с ключами сгенерированными в WM Keeper Classic версии 2.4.0.1 и выше
+для работы с Signer нужно использовать РЕЗЕРВНУЮ копию ключей и пароль от
+РЕЗЕРВНОЙ копии ключей.
+
+Проверить работоспособность wmsigner-а можно и так:
+$ echo -ne "TestString123\004\r\n" | ./wmsigner
+923642a9898f98798c23d5678e23498c98a42c46527...
+ ^^^^^^
+ этот текст уже выведет wmsigner
+
+Если же вы не получили строки из цифр и символов - значит что-то не так.
+Если он выводит ошибку - значит вы неправильно настроили файл wmsigner.ini,
+либо имеете некорректный файл ключей.
+
+При формировании строк с переводами строки используйте только
+последовательность 0x0D 0x0A, подаваемую на подпись и в сертификационный
+центр.
+
+
+wmsigner версии 2.0 имеет следующие опции командной строки:
+
+ -p [--password] : Password for key_file
+ -w [--wmid] : 123456789012 : WMID (12 digits)
+ -s [--sign] : string_to_signification : signing specified string
+ -i [--ini-path] : Correct path to ini_file with ini_file_name *.ini
+ -k [--key-path] : Correct path to key_file with key_file_name
+ -K64 [--key-base64] : Text string in Base64 code, contain the key for wmsigner
+ -h [--help] : Help (this srceen)
+ -v [--version] : Version of program
+
+Таким образом, возможно использование wmsigner'а как без файла wmsigner.ini
+(вариант: он может иметь другое имя), так и без хранения файла ключей на диске
+(он может хранится например в базе данных или в коде программы)
+
+
+Возможные ошибки:
+
+ Error 20
+ Невозможно загрузить конфигурационный файл wmsigner.ini.
+
+ !LoadKeys Error 2
+ Невозможно загрузить файл ключей.
+
+ Error -3
+ Пароль неверный. Возможно Вы используете пароль от основного ключа
+ (не резервной копии).
+
+ Error -4
+ Не задан WMID
+
+ Error -5
+ Не задан пароль от файла ключей
+
+ Error -6
+ Не задан файл ключей
+
+ Segmentation fault.
+ wmsigner был скомпилирован на другой системе или файл ключей больше чем 164 байта.
+
+
+С вопросами обращайтесь на unix@wmtransfer.com
+
+
+Владелец и администратор WM Transfer Ltd.
+Реквизиты: No.35 New Road, P.O. Box 1708, Belize City, Belize,
+Управляющая компания – международная адвокатская компания UAB «DICSA BALTIC»
+(Kraziu Str. 21, 01108, Vilnius, Lithuania), Директор – Giedre Petkunaite.
5 wmsigner-2.0.2/RUNNING_TESTS
@@ -0,0 +1,5 @@
+
+1. Fix values in test.ini (unix and win32 - different path and extensions)
+2. Run:
+ $ make
+ $ make test
147 wmsigner-2.0.2/base64.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************************************************************
+ * Usage this module :
+ * size_t result = code64( JOB [ENCODE or DECODE], char *ASCII_Buffer, size_t ASCII_BUFFER_SIZE,
+ * char *BASE64_Buffer, size_t BASE64_BUFFER_SIZE );
+ * Sample for decode from ascii to base64 :
+ * result = code64( DECODE, char *ASCII_Buffer, size_t ASCII_BUFFER_SIZE, char *BASE64_Buffer, size_t BASE64_BUFFER_SIZE );
+ * Parameter ASCII_BUFFER_SIZE - definition size input to decode sequence !
+ * function strlen() - may be used ONLY for text buffers, otherwize - BINARY DATA, use really size !
+ * Sample for encode from base64 to ascii :
+ * result = code64( ENCODE, char *ASCII_Buffer, size_t ASCII_BUFFER_SIZE, char *BASE64_Buffer, size_t BASE64_BUFFER_SIZE );
+ * Parameter BASE64_BUFFER_SIZE - definition size input to encode sequence !
+ * function strlen() may be used for counting size for BASE64 array, if last symbol == '\0', otherwise use really size !
+ * .........................................................................................................................
+ * Return value:
+ * size_t result - counter, number of bytes in OUTPUT array, whose successfully encoded/decoded.
+ * if result == 0 - error found, abnormal terminating, nothing to encoding or decoding.
+ * .........................................................................................................................
+ * Internal function: idx64( char Ch ); Binary search index in Base64 array, for Ch character in parameter
+ * .........................................................................................................................
+ * This module present "AS IS", absolutely no warranty, if anybody modyfied this source.
+ ****************************************************************************************************************************/
+
+#include "stdafx.h"
+#include "base64.h"
+
+/* Base_64 characters */
+const char Ch64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* Presort array for indexes */
+const INDEX64 Id64[64] = {
+ {'+',62},{'/',63},{'0',52},{'1',53},{'2',54},{'3',55},{'4',56},{'5',57},{'6',58},{'7',59},{'8',60},{'9',61},
+ {'A',0},{'B',1},{'C',2},{'D',3},{'E',4},{'F',5},{'G',6},{'H',7},{'I',8},{'J',9},{'K',10},{'L',11},{'M',12},
+ {'N',13},{'O',14},{'P',15},{'Q',16},{'R',17},{'S',18},{'T',19},{'U',20},{'V',21},{'W',22},{'X',23},{'Y',24},{'Z',25},
+ {'a',26},{'b',27},{'c',28},{'d',29},{'e',30},{'f',31},{'g',32},{'h',33},{'i',34},{'j',35},{'k',36},{'l',37},{'m',38},
+ {'n',39},{'o',40},{'p',41},{'q',42},{'r',43},{'s',44},{'t',45},{'u',46},{'v',47},{'w',48},{'x',49},{'y',50},{'z',51}
+};
+
+/* Base64 ENCODE / DECODE function */
+size_t code64( int job, char *buf_ascii, size_t ascii_size, char *buf_64, size_t buf_64_size )
+{
+ BASE64 b64;
+ size_t i = 0, j = 0, k = 0, i3 = 0; /* job indexes */
+ size_t ask_len = 0; /* Internal variable for size ascii buffer */
+ size_t buf64_len = 0; /* Internal variable for size base64 buffer */
+
+ b64.a[0] = 0; b64.a[1] = 0; b64.a[2] = 0;
+
+/* Decoding to Base64 code */
+ if( job == DECODE ) {
+ ask_len = ascii_size;
+ if( (ascii_size * 4 / 3) > buf_64_size ) return( CODE_ERR ); /* No enough space to decoding */
+ if( ask_len == 0 ) return( CODE_ERR );
+ i3 = (int) 3 * (ask_len / 3); /* Dividing by 3 */
+ if( i3 > 0 ) k = 3 - ask_len + i3; /* End of seq (1 or 2) */
+ if( ask_len < 3 ) k = 3 - ask_len;
+
+ while( i < i3 ) {
+ b64.a[2] = buf_ascii[i];
+ b64.a[1] = buf_ascii[i+1];
+ b64.a[0] = buf_ascii[i+2];
+ buf_64[j++] = Ch64[b64.b.b0];
+ buf_64[j++] = Ch64[b64.b.b1];
+ buf_64[j++] = Ch64[b64.b.b2];
+ buf_64[j++] = Ch64[b64.b.b3];
+ i+=3;
+ }
+
+ if( k == 2 ) {
+ b64.a[2] = buf_ascii[i];
+ b64.a[1] = 0;
+ b64.a[0] = 0;
+ buf_64[j++] = Ch64[b64.b.b0];
+ buf_64[j++] = Ch64[b64.b.b1];
+ buf_64[j++] = '=';
+ buf_64[j++] = '=';
+ }
+
+ if( k == 1 ) {
+ b64.a[2] = buf_ascii[i];
+ b64.a[1] = buf_ascii[i+1];
+ b64.a[0] = 0;
+ buf_64[j++] = Ch64[b64.b.b0];
+ buf_64[j++] = Ch64[b64.b.b1];
+ buf_64[j++] = Ch64[b64.b.b2];
+ buf_64[j++] = '=';
+ }
+
+ return( j );
+ }
+
+/* Restoring original characters */
+ if( job == ENCODE ) {
+ buf64_len = buf_64_size;
+ if( buf64_len < 4 ) return( CODE_ERR ); /* Too small input buffer */
+ if( (buf_64_size * 3 / 4) > ascii_size ) return( CODE_ERR ); /* No enough space to encoding */
+ i3 = buf64_len / 4;
+ k = buf64_len - i3 * 4;
+ if( k ) return( CODE_ERR ); /* Illegal size for input sequence !! */
+ k = 0; /* Counter original bytes for output */
+
+ for( i = 0; i < buf64_len; i+=4 ) {
+ b64.b.b0 = idx64( buf_64[i] );
+ b64.b.b1 = idx64( buf_64[i+1] );
+ b64.b.b2 = 0; b64.b.b3 = 0;
+ if( buf_64[i+2] != '=' ) b64.b.b2 = idx64( buf_64[i+2] );
+ else k--;
+ if( buf_64[i+3] != '=' ) b64.b.b3 = idx64( buf_64[i+3] );
+ else k--;
+ buf_ascii[j++] = b64.a[2]; k++;
+ buf_ascii[j++] = b64.a[1]; k++;
+ buf_ascii[j++] = b64.a[0]; k++;
+ }
+
+ return( k );
+ }
+
+ return( CODE_ERR ); /* Unknown command ! */
+}
+
+/* Binary search character's index in array */
+int idx64( char ch )
+{
+ int start = 0;
+ int pos = 32;
+ int end = 63;
+
+ while( (pos >= start) || (pos <= end) ) {
+ if( ch == Id64[start].Ch ) return( Id64[start].Id );
+ if( ch == Id64[pos].Ch ) return( Id64[pos].Id );
+ if( ch == Id64[end].Ch ) return( Id64[end].Id );
+
+ if( ch > Id64[pos].Ch ) {
+ start = pos;
+ }
+
+ if( ch < Id64[pos].Ch ) {
+ end = pos;
+ }
+
+ pos = (int) (start+end) / 2;
+ }
+
+/* Illegal character found, task aborted ! */
+ fprintf( stderr, "\n\rBase64 Fatal Error: Illegal character found : '%c' [%d] - No Base64 legal character!!\n\r", ch, ch );
+ exit(1);
+ return(0);
+}
48 wmsigner-2.0.2/base64.h
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef __BASE64_DEFINED___
+#define __BASE64_DEFINED___
+
+#define ENCODE 0
+#define DECODE 1
+
+#define CODE_ERR 0
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define MAXBUFFER 4096 // Don`t change this parameter !!!
+#define READBYTES 3072 // Don`t change this parameter !!!
+
+/* Bits BASE64 structure */
+typedef struct __Bits64__ {
+ unsigned b3 : 6; /* 1 Base 64 character */
+ unsigned b2 : 6; /* 2 Base 64 character */
+ unsigned b1 : 6; /* 3 Base 64 character */
+ unsigned b0 : 6; /* 4 Base 64 character */
+} BITS, *BITSPTR;
+
+/* Union of Bits & Bytes */
+typedef union __Base64__ {
+ char a[3]; /* Byte array in the case */
+ BITS b; /* Bits fields in the case */
+} BASE64;
+
+/* Base_64 index structure */
+
+typedef struct __index64__ {
+ char Ch;
+ int Id;
+} INDEX64, *INDEX64PTR;
+
+/* Prototypes */
+size_t code64( int job, char *buf_ascii, size_t ascii_size, char *buf_64, size_t buf_64_size );
+int idx64( char ch );
+
+#endif /* __BASE64_DEFINED___ */
419 wmsigner-2.0.2/cmdbase.cpp
@@ -0,0 +1,419 @@
+#include "stdafx.h"
+#include <stdio.h>
+#include <stdlib.h>
+//#include <io.h>
+#include <string.h>
+#include "ctype.h"
+#include "cmdbase.h"
+
+WORD SwitchIndian(WORD n1)
+{
+#ifndef LOWBYTEFIRST
+ WORD n2;
+
+ char* ps=(char*)&n1;
+ char* pd=(char*)&n2;
+ pd[1] = ps[0];
+ pd[0] = ps[1];
+
+ return n2;
+#else
+ return n1;
+#endif
+}
+
+DWORD SwitchIndian(DWORD n1)
+{
+#ifndef LOWBYTEFIRST
+ DWORD n2;
+
+ char* ps=(char*)&n1;
+ char* pd=(char*)&n2;
+ pd[3] = ps[0];
+ pd[2] = ps[1];
+ pd[1] = ps[2];
+ pd[0] = ps[3];
+
+ return n2;
+#else
+ return n1;
+#endif
+}
+
+szptr::szptr(const char *csz)
+{
+ if (csz)
+ {
+ sz = new char[::strlen(csz)+4];
+ strcpy(sz, csz);
+ }
+ else
+ sz = NULL;
+}
+
+szptr::szptr(const szptr& cszptr)
+{
+ if ((const char *)cszptr)
+ {
+ sz = new char[cszptr.strlen()+4];
+ sz = strcpy(sz, cszptr);
+ }
+ else
+ sz = (const char *)cszptr ? strcpy(new char[cszptr.strlen()+4], cszptr) : NULL;
+}
+
+szptr::~szptr()
+{
+ if(sz) delete[] sz;
+}
+
+char* szptr::operator = (char *csz)
+{
+ if(sz && csz)
+ {
+ if(!strcmp(csz,sz))
+ return sz;
+ }
+
+ char *szprev = sz;
+ if(csz)
+ {
+ sz = new char[::strlen(csz)+4];
+ sz = strcpy(sz, csz);
+ }
+ else
+ sz = NULL;
+
+ if(szprev)
+ delete[] szprev;
+
+ return sz;
+}
+
+szptr& szptr::operator = (const szptr& cszptr)
+{
+ if(sz && cszptr.sz)
+ if(!strcmp(cszptr,sz))
+ return *this;
+
+ char *szprev = sz;
+ if(cszptr)
+ {
+ sz = new char[::strlen(cszptr)+4];
+ sz = strcpy(sz, cszptr);
+ }
+ else
+ sz = NULL;
+ if(szprev)
+ delete[] szprev;
+ return *this;
+}
+
+szptr& szptr::operator += (const szptr& cszptr)
+{
+// if(!&cszptr) return *this;
+ if(!cszptr.strlen()) return *this;
+
+ char *szprev = sz;
+ sz = new char[strlen()+cszptr.strlen()+4];
+ if(szprev)
+ {
+ strcpy(sz, szprev);
+ delete[] szprev;
+ }
+ else
+ sz[0] = '\0';
+
+ strcat(sz, cszptr);
+ return *this;
+}
+
+szptr& szptr::TrimRight()
+{
+ if (NULL== this->sz)
+ return *this;
+ char* lpsz = this->sz;
+ char* lpszLast = NULL;
+
+ while (*lpsz != '\0')
+ {
+ if (*lpsz == ' ')
+ {
+ if (lpszLast == NULL)
+ lpszLast = lpsz;
+ }
+ else
+ lpszLast = NULL;
+ lpsz = ((char*)lpsz)+1;
+ }
+
+ if (lpszLast != NULL)
+ {
+ *lpszLast = '\0';
+ }
+ return *this;
+}
+
+szptr& szptr::TrimLeft()
+{
+ if (NULL== this->sz)
+ return *this;
+ char* lpsz = this->sz;
+ int nLen = (int)::strlen(sz);
+ while ((*lpsz==' '))
+ lpsz = ((char*)lpsz)+1;
+
+ if (lpsz != sz)
+ {
+ int nDataLength = (int)nLen - (int)(lpsz - sz);
+ memmove(sz, lpsz, (nDataLength+1)*sizeof(char));
+ }
+ return *this;
+}
+
+static char *dwordFromBuf(DWORD *wMember, char *szNextElemBufPtr)
+{
+ *wMember = SwitchIndian(*((DWORD*)szNextElemBufPtr));
+ return (szNextElemBufPtr+sizeof(DWORD));
+}
+
+static char *wordFromBuf(WORD *wMember, char *szNextElemBufPtr)
+{
+ *wMember = SwitchIndian(*((WORD*)szNextElemBufPtr));
+ return (szNextElemBufPtr+sizeof(WORD));
+}
+
+static char *dwordToBuf(char *szNextElemBufPtr, DWORD wMember)
+{
+ *((DWORD*)szNextElemBufPtr) = wMember;
+ return (szNextElemBufPtr+sizeof(DWORD));
+}
+
+static char *wordToBuf(char *szNextElemBufPtr, WORD wMember)
+{
+ *((WORD*)szNextElemBufPtr) = wMember;
+ return (szNextElemBufPtr+sizeof(WORD));
+}
+
+
+/**/
+Keys::Keys()
+ :dwReserv(0)
+{
+ memset(arwEKey, 0, (MAX_UNIT_PRECISION) * 2);
+ memset(arwNKey, 0, (MAX_UNIT_PRECISION) * 2);
+ wEKeyBase= wNKeyBase = 0;
+}
+
+Keys::Keys(const Keys& keysFrom)
+{
+ dwReserv = keysFrom.dwReserv;
+ wEKeyBase= wNKeyBase = 0;
+ memcpy(arwEKey, keysFrom.arwEKey, (MAX_UNIT_PRECISION) * 2);
+ memcpy(arwNKey, keysFrom.arwEKey, (MAX_UNIT_PRECISION) * 2);
+ wEKeyBase = keysFrom.wEKeyBase;
+ wNKeyBase = keysFrom.wNKeyBase;
+}
+
+Keys& Keys::operator=(const Keys& keysFrom)
+{
+ dwReserv = keysFrom.dwReserv;
+ memcpy(arwEKey, keysFrom.arwEKey, (MAX_UNIT_PRECISION) * 2);
+ memcpy(arwNKey, keysFrom.arwNKey, (MAX_UNIT_PRECISION) * 2);
+ wEKeyBase = keysFrom.wEKeyBase;
+ wNKeyBase = keysFrom.wNKeyBase;
+ return *this;
+}
+
+DWORD Keys::GetMembersSize()
+{
+ return (
+ sizeof(dwReserv)
+ + GetKeyBaseB(arwEKey)
+ + GetKeyBaseB(arwNKey)
+ + sizeof(wEKeyBase)
+ + sizeof(wNKeyBase));
+}
+
+char *Keys::LoadMembers(char *BufPtr)
+{
+ char *ptrNextMemb = dwordFromBuf(&dwReserv, BufPtr);
+ unsigned int i = 0;
+ ptrNextMemb = wordFromBuf(&wEKeyBase, ptrNextMemb);
+ memcpy(arwEKey, ptrNextMemb, wEKeyBase);
+ for( i=0;i<wEKeyBase/sizeof(arwEKey[0]);i++)
+ { arwEKey[i] = SwitchIndian(arwEKey[i]); }
+
+ ptrNextMemb += wEKeyBase;
+
+ ptrNextMemb = wordFromBuf(&wNKeyBase, ptrNextMemb);
+ memcpy(arwNKey, ptrNextMemb, wNKeyBase);
+ for( i=0;i<wNKeyBase/sizeof(arwNKey[0]);i++)
+ { arwNKey[i] = SwitchIndian(arwNKey[i]); }
+
+ ptrNextMemb += wNKeyBase;
+
+ return ptrNextMemb;
+}
+
+char *Keys::SaveMembers(char *BufPtr)
+{
+ char *ptrNextMemb = dwordToBuf(BufPtr, dwReserv);
+
+ wEKeyBase = (WORD)GetKeyBaseB(arwEKey);
+ ptrNextMemb = wordToBuf(ptrNextMemb, wEKeyBase);
+ memcpy(ptrNextMemb, arwEKey, wEKeyBase);
+ ptrNextMemb += wEKeyBase;
+
+ wNKeyBase = (WORD)GetKeyBaseB(arwNKey);
+ ptrNextMemb = wordToBuf(ptrNextMemb, wNKeyBase);
+ memcpy(ptrNextMemb, arwNKey, wNKeyBase);
+ ptrNextMemb += wNKeyBase;
+
+ return ptrNextMemb;
+}
+
+
+void Keys::RecalcBase()
+{
+ wEKeyBase = (WORD)GetKeyBaseB(arwEKey);
+ wNKeyBase = (WORD)GetKeyBaseB(arwNKey);
+}
+
+int Keys::LoadFromBuffer(const char *Buf, DWORD dwBufLen)
+{
+ KeyFileFormat *keyFmt = (KeyFileFormat *)Buf;
+ DWORD ardwRecievedCRC[4];
+ DWORD ardwCheckedCRC[4];
+ DWORD i = 0;
+
+ if(dwBufLen < KeyFileFormat::sizeof_header)
+ return _CMDLOAD_ERR_BUF_LEN_;
+
+ if(dwBufLen-2*sizeof(DWORD) >= SwitchIndian(keyFmt->dwLenBuf))
+ {
+ for(i=0; i<4; i++)
+ ardwRecievedCRC[i] = SwitchIndian(keyFmt->dwCRC[i]);
+ for(i=0; i<4; i++) keyFmt->dwCRC[i] = 0;
+ CountCrcMD4(ardwCheckedCRC, Buf, SwitchIndian(keyFmt->dwLenBuf)+KeyFileFormat::sizeof_header);
+
+ for(i=0; i<4; i++) keyFmt->dwCRC[i] = SwitchIndian(ardwRecievedCRC[i]);
+
+ bool bCrcGood = true;
+ for(i=0; i<4; i++)
+ if(ardwCheckedCRC[i]!=ardwRecievedCRC[i])
+ {
+ bCrcGood = false;
+ break;
+ }
+
+ if(bCrcGood)
+ {
+ LoadMembers(keyFmt->ptrBuffer);
+ return 0;
+ }
+ else
+ return _CMDLOAD_ERR_CMD_CRC_;
+ }
+ else
+ return _CMDLOAD_ERR_BUF_LEN_;
+}
+
+int Keys::SaveIntoBuffer(char **ptrAllocBuf, DWORD *dwBufLen)
+{
+ char *Buf;
+ KeyFileFormat *cmdFmt;
+ DWORD dwMembersSize;
+ DWORD dwBufSize, i;
+ BOOL bRC = false;
+
+ dwMembersSize = GetMembersSize();
+
+ dwBufSize = dwMembersSize+KeyFileFormat::sizeof_header;
+ Buf = new char[dwBufSize];
+ memset(Buf, 0, dwBufSize); // Clear for Trail...
+ cmdFmt = (KeyFileFormat *)Buf;
+ if(Buf)
+ {
+ char *BufMemb;
+ BufMemb = cmdFmt->ptrBuffer;
+
+ if(SaveMembers(BufMemb))
+ {
+ cmdFmt->wReserved1 = 0x81;
+ cmdFmt->wSignFlag = 0;
+ cmdFmt->dwLenBuf = dwMembersSize;
+
+ for(i=0; i<4; i++) cmdFmt->dwCRC[i] = 0;
+ CountCrcMD4(cmdFmt->dwCRC, Buf, dwBufSize); //*((WORD *)(Buf+sizeof(WORD)))=
+ *dwBufLen = dwBufSize;
+ *ptrAllocBuf = Buf;
+ bRC = true;
+ }
+ }
+ else
+ bRC = false; // NOT_ENOUGH_MEMORY
+
+ return bRC;
+}
+
+ bool Keys::CountCrcMD4(DWORD *dwCRC, const char *Buf, DWORD dwBufLenBytes)
+{
+ int b,bitcount;
+ MDstruct MD;
+
+ MDbegin(&MD);
+ for(b=0,bitcount=512; (unsigned int)b<dwBufLenBytes/64+1; b++)
+ {
+ if((unsigned int)b==dwBufLenBytes/64) bitcount = (dwBufLenBytes%64)<<3;
+ MDupdate(&MD, (unsigned char *)(Buf+b*64), bitcount);
+ }
+ MDupdate(&MD, (unsigned char *)Buf, 0);
+
+ for(b=0; b<4; b++) dwCRC[b] = MD.buffer[b];
+
+ return true;
+}
+
+bool us2sz(const unsigned short *buf, int len, char *szBuffer)
+{
+ char tmp[5];
+ szBuffer[0] = '\0';
+
+ for(int i=0;i<len;i++)
+ {
+ sprintf(tmp, "%04x", buf[i]);
+ strcat(szBuffer, tmp);
+ }
+ return true;
+}
+
+char stohb(char s)
+{
+ if ( s>='0' && s<='9') return (s-'0');
+ else
+ if ( s>='A' && s<='F') return (s-'A'+0xA);
+ else
+ if ( s>='a' && s<='f') return (s-'a'+0xA);
+ return 0;
+}
+
+bool sz2us(const char *szBuffer, unsigned short *usBuf)
+{
+ const char* p = szBuffer;
+ int l = (int)strlen(szBuffer);
+ unsigned short cell = 0;
+ for(int i=0,k=0; i<l; i+=4) {
+ cell = 0;
+ cell = stohb(*p++);
+ cell <<= 4;
+ cell |= stohb(*p++);
+ cell <<= 4;
+ cell |= stohb(*p++);
+ cell <<= 4;
+ cell |= stohb(*p++);
+ usBuf[k++] = cell;
+ }
+ return true;
+}
+//----
111 wmsigner-2.0.2/cmdbase.h
@@ -0,0 +1,111 @@
+#ifndef __CMDBASE_INCLUDE__
+#define __CMDBASE_INCLUDE__
+#include "stdafx.h"
+#include "crypto.h"
+#include "md4.h"
+#include <stdio.h>
+#include "string.h"
+//--------------------
+
+#ifndef _WIN32
+#define _NOT_WIN32
+#endif
+
+#if defined(__FreeBSD__) && __FreeBSD__ < 5 /* for FreeBSD version <= 4 */
+#include <inttypes.h>
+#elif defined(_NOT_WIN32)
+#include <stdint.h>
+#endif
+
+#ifndef _WIN32
+typedef uint32_t DWORD;
+typedef bool BOOL;
+typedef uint8_t BYTE;
+typedef uint16_t WORD;
+#endif
+
+
+//--------------------
+#define LOWBYTEFIRST
+#define EBITS (48)
+#define KEYBITS (528)
+
+#define MAX_BIT_PRECISION (2048)
+#define MAX_UNIT_PRECISION (MAX_BIT_PRECISION/(sizeof(unsigned short)*8))
+
+#define _CMDLOAD_ERR_CMD_CRIPTION_ 1
+#define _CMDLOAD_ERR_CMD_CRC_ 2
+#define _CMDLOAD_ERR_BUF_LEN_ 3
+#define _CMDLOAD_ERR_CMD_DECODE_ 4
+#define _CMDLOAD_ERR_CMD_CODE_ 5
+#define _CMDLOAD_ERR_NULL_KEY_ 6
+
+class szptr
+{
+ char *sz;
+
+public:
+ szptr() { sz = NULL; }
+ szptr(const char *csz);
+ szptr(const szptr& cszptr);
+ ~szptr();
+
+ char* operator = (char *csz);
+ szptr& operator = (const szptr& cszptr);
+ szptr& operator += (const szptr& cszptr);
+ inline void ReplaceIncluding(char *szp) { if(sz) delete sz; sz = szp; }
+ inline char operator*() { return sz ? *sz : '\0'; }
+ inline char operator[](int i) const { return sz ? *(sz+i) : '\0'; }
+ inline operator char const * const () const { return sz; }
+ int strlen() const {
+ if (sz) return (int)::strlen(sz);
+ else return 0;
+ }
+ inline bool operator==(const szptr& s) const { return (sz && s.sz) ? (strcmp(s.sz,sz)==0) : (sz == s.sz); }
+ inline bool operator!=(const szptr& s) const { return (sz && s.sz) ? (strcmp(s.sz,sz)!=0) : (sz != s.sz); }
+
+ szptr& TrimLeft();
+ szptr& TrimRight();
+};
+
+
+WORD SwitchIndian(WORD n1);
+DWORD SwitchIndian(DWORD n1);
+
+struct KeyFileFormat
+{
+ enum {sizeof_header = sizeof(WORD)*2 + sizeof(DWORD)*5, sizeof_crc = (sizeof(DWORD)*4)};
+ WORD wReserved1;
+ WORD wSignFlag;
+ DWORD dwCRC[4];
+ DWORD dwLenBuf;
+ char ptrBuffer[1];
+};
+
+struct Keys
+{
+ DWORD dwReserv;
+ WORD arwEKey[MAX_UNIT_PRECISION];
+ WORD arwNKey[MAX_UNIT_PRECISION];
+ WORD wEKeyBase;
+ WORD wNKeyBase;
+
+ Keys();
+ Keys(const Keys& keysFrom);
+ Keys& operator=(const Keys& KeysFrom);
+ virtual DWORD GetMembersSize();
+ virtual char* LoadMembers(char *BufPtr);
+ virtual int LoadFromBuffer(const char *Buf, DWORD dwBufLen);
+ virtual char* SaveMembers(char *BufPtr);
+ virtual int SaveIntoBuffer(char **ptrAllocBuf, DWORD *dwBufLen);
+
+ static bool CountCrcMD4(DWORD *dwCRC, const char *Buf, DWORD dwBufLenBytes);
+ void RecalcBase();
+};
+
+
+bool us2sz(const unsigned short *buf, int len, char *szBuffer);
+char stohb(char s);
+bool sz2us(const char *szBuffer, unsigned short *usBuf);
+#endif
+//---
74 wmsigner-2.0.2/code64.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************************************************************
+ * Base64 Encoder / Decoder module. Light Version 1.0
+ * Written by Georgy Mushkarev (c) for wmsigner Library. Moscow, Russia, 1992-2007.
+ ****************************************************************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "base64.h"
+
+/* Main functions */
+
+int main( int argc, char *argv[] );
+void fatal_error( char *msg );
+
+void fatal_error( char *msg )
+{
+ fprintf( stderr, "%s", msg);
+ exit(2);
+}
+
+
+int main( int argc, char *argv[] )
+{
+ FILE *inputfile;
+ size_t Counter = 0;
+ size_t Bytes = 0;
+ size_t i = 0;
+
+ char buffer_inp[MAXBUFFER];
+ char buffer_out[MAXBUFFER];
+
+ if( argc == 1 || strcmp( argv[1], "-h" ) == 0 || strcmp( argv[1], "--help") == 0 ) {
+ printf( "Program for Encode / Decode input File in Base64 system. Version 1.0\n\r");
+ printf( "Usage to encode to Base64: code64 -K64 [--key64] Input_File [> Output_File]\n\r");
+ printf( "Usage to decode to Bytes : code64 -E64 [--enc64] Input_File [> Output_File]\n\r");
+ printf( "Author: Georgy Mushkarev (c), Moscow 2007\n\r");
+ exit(1);
+ }
+
+ if( argc != 3) fatal_error("Invalid parameters in command string !\n\r");
+
+ /* Decoding Input file */
+ if( (strcmp( argv[1], "-K64" ) == 0) || (strcmp( argv[1], "--key64") == 0) ) {
+ inputfile = fopen( argv[2], "r+b" );
+ if( !inputfile ) fatal_error("Input file open error!\n\r");
+ while( TRUE ) {
+ Counter = fread( (void *) buffer_inp, sizeof( char ), READBYTES, inputfile);
+ Bytes = code64( DECODE, buffer_inp, Counter, buffer_out, MAXBUFFER );
+ if( Bytes == CODE_ERR ) fatal_error("Decode fatal error. Task stopped !\n\r");
+ for( i = 0; i < Bytes; i++ ) printf("%c", buffer_out[i]);
+ if( Counter < READBYTES ) break;
+ }
+ fclose( inputfile );
+ exit(0);
+ }
+
+ /* Encoding Input file */
+ if( (strcmp( argv[1],"-E64") == 0) || (strcmp( argv[1], "--enc64") == 0) ) {
+ inputfile = fopen( argv[2], "r+b" );
+ if( !inputfile ) fatal_error("Input file open error! Task stopped !\n\r");
+ while( TRUE ) {
+ Counter = fread( (void *) buffer_inp, sizeof( char ), READBYTES, inputfile);
+ Bytes = code64( ENCODE, buffer_out, MAXBUFFER, buffer_inp, Counter );
+ if( Bytes == CODE_ERR ) fatal_error("Encode fatal error, illegal input sequience. Task stopped !\n\r");
+ for( i = 0; i < Bytes; i++ ) printf("%c", buffer_out[i]);
+ if( Counter < READBYTES ) break;
+ }
+ fclose( inputfile );
+ exit(0);
+ }
+
+ fatal_error("Invalid argument[s] in command string !\n\r");
+ return(1);
+}
155 wmsigner-2.0.2/crypto.cpp
@@ -0,0 +1,155 @@
+#include "stdafx.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "crypto.h"
+#include "rsalib1.h"
+#include <memory.h>
+
+
+unsigned short SwitchIndian(unsigned short n1);
+
+unsigned int GetCLenB(int len, const unsigned short *n, short KeyBits)
+{
+ CRSALib rsalib((KeyBits + 15)>> 4);
+ rsalib.set_precision((KeyBits + 15) >> 4);
+ int blocksize = rsalib.significance((unsigned short *)n);
+ int workblocksize = blocksize-1;
+ int len_and_sizeW = (len+sizeof(short)+1) >> 1;
+ int hvost = (len_and_sizeW)%workblocksize;
+ if (hvost) hvost = 1;
+ int newLen = (((len_and_sizeW) / (workblocksize)) + hvost) * blocksize;
+ return (newLen*2);
+}
+
+unsigned int CrpB(char* crp, char* p, int len, const unsigned short * e, const unsigned short *n, short KeyBits)
+{
+
+ CRSALib rsalib((KeyBits + 15)>> 4);
+ rsalib.set_precision((KeyBits + 15) >> 4);
+ int blocksize = rsalib.significance((unsigned short *)n)*2;
+ int workblocksize = blocksize-2;
+ int ostb = 2;
+ int i=0, stP=0, endP=0, stC=0;
+ char pb[CRSALib::MAX_UNIT_PRECISION*2], cb[CRSALib::MAX_UNIT_PRECISION*2];
+ char *buf = (char *)malloc(len+ostb);
+ memcpy(buf+sizeof(short), p, len);
+ *(short*)buf = SwitchIndian((short)len);
+ int iLen = len+sizeof(short);
+ stP = 0;
+ stC = 0;
+ int res = 0, res1 = 0;
+
+ do
+ {
+ memset(cb, 0, CRSALib::MAX_UNIT_PRECISION*2);
+ memset(pb, 0, CRSALib::MAX_UNIT_PRECISION*2);
+
+ endP = ((workblocksize < iLen) ? workblocksize : iLen);
+ memcpy(pb, buf+stP, endP);
+ for(int h=0;h<endP/2;h++)
+ {
+ ((unsigned short*)pb)[h] = SwitchIndian(((unsigned short*)pb)[h]);
+ }
+#ifdef _DEBUG
+ for(int h=0;h<endP/2;h++)
+ {
+ printf("X:%d ", ((unsigned short*)pb)[h]);
+ }
+#endif
+
+ if ((res = rsalib.mp_modexp((unsigned short*)cb, (unsigned short*)pb, (unsigned short *)e, (unsigned short *)n)) != 0)
+ {
+ res1 = res;
+ }
+
+ memcpy(crp+stC, cb, blocksize);
+
+ stP += endP;
+ stC += blocksize;
+ iLen -= (workblocksize);
+ } while (iLen > 0);
+
+ free(buf);
+
+ return GetCLenB(len, n);
+}
+
+unsigned int DCrpB(char* dcrp, int* dlen, char* c, int len, const unsigned short * d, const unsigned short *n, short KeyBits)
+{
+ CRSALib rsalib((KeyBits + 15)>> 4);
+ rsalib.set_precision((KeyBits + 15) >> 4);
+ int blocksize = rsalib.significance((unsigned short *)n)*2;
+ if (0==blocksize)
+ {
+ *dlen = 0;
+ return 0;
+ }
+ if (len < blocksize)
+ {
+ *dlen = 0;
+ return 0;
+ }
+ int workblocksize = blocksize-2;
+ int rcLen = 0, iLen = len;
+ int stP = 0, stC = 0;
+
+ char *buf = (char *)malloc(len);
+ memset(buf, 0, len);
+
+ char pb[CRSALib::MAX_UNIT_PRECISION*2], cb[CRSALib::MAX_UNIT_PRECISION*2];
+
+ int res = 0, res1 = 0;
+ do
+ {
+ memset(cb, 0, CRSALib::MAX_UNIT_PRECISION*2);
+ memset(pb, 0, CRSALib::MAX_UNIT_PRECISION*2);
+
+ memcpy(cb, c+stC, blocksize);
+
+ if ((res = rsalib.mp_modexp((unsigned short*)pb, (unsigned short*)cb, (unsigned short *)d, (unsigned short *)n))!=0)
+ {
+ res1 = res;
+
+ }
+
+
+ memcpy(buf+stP, pb, workblocksize);
+
+ stC += blocksize;
+ stP += workblocksize;
+ iLen -= blocksize;
+ } while ((iLen > 0)&&(iLen >= blocksize));
+
+ rcLen = *(unsigned short*)buf;
+
+ if (len >= rcLen)
+ {
+ *dlen = rcLen;
+ memcpy(dcrp, buf+sizeof(short), rcLen);
+ }
+ else
+ {
+ rcLen = 0;
+ }
+ free(buf);
+ return rcLen;
+}
+
+unsigned int GetKeyBase(const unsigned short *n)
+{
+ if(!n) return 0;
+ CRSALib rsalib(CRSALib::MAX_UNIT_PRECISION);
+ rsalib.set_precision(CRSALib::MAX_UNIT_PRECISION);
+ int blocksize = rsalib.significance((unsigned short *)n);
+ return blocksize;
+}
+
+unsigned int GetKeyBaseB(const unsigned short *n)
+{
+ if(!n) return 0;
+ CRSALib rsalib(CRSALib::MAX_UNIT_PRECISION);
+ rsalib.set_precision(CRSALib::MAX_UNIT_PRECISION);
+ int blocksize = rsalib.significance((unsigned short *)n);
+ return blocksize * 2;
+}
+//---
17 wmsigner-2.0.2/crypto.h
@@ -0,0 +1,17 @@
+#ifndef __CRYPTO_H__
+#define __CRYPTO_H__
+#include "stdafx.h"
+
+#ifndef keybits
+ #define ebits 48
+ #define keybits 528
+#endif
+
+unsigned int CrpB(char* crp, char* p, int len, const unsigned short * e, const unsigned short *n, short KeyBits=keybits);
+unsigned int DCrpB(char* dcrp, int* dlen, char* c, int len, const unsigned short * d, const unsigned short *n, short KeyBits=keybits);
+unsigned int GetCLenB(int len, const unsigned short *n, short KeyBits=keybits);
+unsigned int GetKeyBaseB(const unsigned short *n);
+unsigned int GetKeyBase(const unsigned short *n);
+
+#endif
+//---
192 wmsigner-2.0.2/md4.cpp
@@ -0,0 +1,192 @@
+#include "stdafx.h"
+#include <stdio.h>
+#include "md4.h"
+#include "cmdbase.h"
+
+#define TRUE 1
+#define FALSE 0
+
+#define I0 0x67452301L
+#define I1 0xefcdab89L
+#define I2 0x98badcfeL
+#define I3 0x10325476L
+#define C2 013240474631L
+#define C3 015666365641L
+
+#define fs1 3
+#define fs2 7
+#define fs3 11
+#define fs4 19
+#define gs1 3
+#define gs2 5
+#define gs3 9
+#define gs4 13
+#define hs1 3
+#define hs2 9
+#define hs3 11
+#define hs4 15
+
+
+#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
+#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
+#define h(X,Y,Z) (X^Y^Z)
+#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
+#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
+#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
+#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
+
+void MDprint(MDptr MDp)
+{
+ int i,j;
+ for (i=0;i<4;i++)
+ for (j=0;j<32;j=j+8)
+ printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
+}
+
+void MDbegin(MDptr MDp)
+{
+ int i;
+ MDp->buffer[0] = I0;
+ MDp->buffer[1] = I1;
+ MDp->buffer[2] = I2;
+ MDp->buffer[3] = I3;
+ for (i=0;i<8;i++)
+ MDp->count[i] = 0;
+ MDp->done = 0;
+}
+
+#define revx { t = (*X << 16) | (*X >> 16); *X++ = ((t & 0xFF00FF00L) >> 8) | ((t & 0x00FF00FFL) << 8); }
+
+void MDreverse(Word32Type *X)
+{
+ register Word32Type t;
+ revx; revx; revx; revx; revx; revx; revx; revx;
+ revx; revx; revx; revx; revx; revx; revx; revx;
+}
+
+static void MDblock(MDptr MDp, Word32Type *X)
+{
+ register Word32Type tmp, A, B, C, D;
+#ifndef LOWBYTEFIRST
+ MDreverse(X);
+#endif
+ A = MDp->buffer[0];
+ B = MDp->buffer[1];
+ C = MDp->buffer[2];
+ D = MDp->buffer[3];
+ ff(A , B , C , D , 0 , fs1);
+ ff(D , A , B , C , 1 , fs2);
+ ff(C , D , A , B , 2 , fs3);
+ ff(B , C , D , A , 3 , fs4);
+ ff(A , B , C , D , 4 , fs1);
+ ff(D , A , B , C , 5 , fs2);
+ ff(C , D , A , B , 6 , fs3);
+ ff(B , C , D , A , 7 , fs4);
+ ff(A , B , C , D , 8 , fs1);
+ ff(D , A , B , C , 9 , fs2);
+ ff(C , D , A , B , 10 , fs3);
+ ff(B , C , D , A , 11 , fs4);
+ ff(A , B , C , D , 12 , fs1);
+ ff(D , A , B , C , 13 , fs2);
+ ff(C , D , A , B , 14 , fs3);
+ ff(B , C , D , A , 15 , fs4);
+ gg(A , B , C , D , 0 , gs1);
+ gg(D , A , B , C , 4 , gs2);
+ gg(C , D , A , B , 8 , gs3);
+ gg(B , C , D , A , 12 , gs4);
+ gg(A , B , C , D , 1 , gs1);
+ gg(D , A , B , C , 5 , gs2);
+ gg(C , D , A , B , 9 , gs3);
+ gg(B , C , D , A , 13 , gs4);
+ gg(A , B , C , D , 2 , gs1);
+ gg(D , A , B , C , 6 , gs2);
+ gg(C , D , A , B , 10 , gs3);
+ gg(B , C , D , A , 14 , gs4);
+ gg(A , B , C , D , 3 , gs1);
+ gg(D , A , B , C , 7 , gs2);
+ gg(C , D , A , B , 11 , gs3);
+ gg(B , C , D , A , 15 , gs4);
+ hh(A , B , C , D , 0 , hs1);
+ hh(D , A , B , C , 8 , hs2);
+ hh(C , D , A , B , 4 , hs3);
+ hh(B , C , D , A , 12 , hs4);
+ hh(A , B , C , D , 2 , hs1);
+ hh(D , A , B , C , 10 , hs2);
+ hh(C , D , A , B , 6 , hs3);
+ hh(B , C , D , A , 14 , hs4);
+ hh(A , B , C , D , 1 , hs1);
+ hh(D , A , B , C , 9 , hs2);
+ hh(C , D , A , B , 5 , hs3);
+ hh(B , C , D , A , 13 , hs4);
+ hh(A , B , C , D , 3 , hs1);
+ hh(D , A , B , C , 11 , hs2);
+ hh(C , D , A , B , 7 , hs3);
+ hh(B , C , D , A , 15 , hs4);
+ MDp->buffer[0] += A;
+ MDp->buffer[1] += B;
+ MDp->buffer[2] += C;
+ MDp->buffer[3] += D;
+
+#ifndef LOWBYTEFIRST
+ MDreverse(X);
+#endif
+}
+
+void MDupdate(MDptr MDp, unsigned char *X, Word32Type count)
+{
+ int i, byte ;
+ Word32Type tmp, bit, mask;
+ unsigned char XX[64];
+ unsigned char *p;
+ if(count == 0 && MDp->done)
+ return;
+ if (MDp->done)
+ {
+ return;
+ }
+ tmp = count;
+ p = MDp->count;
+ while (tmp)
+ {
+ tmp += *p;
+ *p++ = (unsigned char) tmp;
+ tmp = tmp >> 8;
+ }
+ if (count == 512)
+ {
+ MDblock(MDp,(Word32Type *)X);
+ }
+ else
+ if (count > 512)
+ {
+ return;
+ }
+ else
+ {
+ byte = (int) count >> 3;
+ bit = count & 7;
+ for (i=0;i<=byte;i++)
+ XX[i] = X[i];
+ for (i=byte+1;i<64;i++)
+ XX[i] = 0;
+ mask = 1 << (7 - bit);
+ XX[byte] = (unsigned char) (XX[byte] | (unsigned char)mask) & ~((unsigned char)mask - 1);
+ if (byte <= 55)
+ {
+ for (i=0;i<8;i++)
+ XX[56+i] = MDp->count[i];
+ MDblock(MDp,(Word32Type *)XX);
+ }
+ else
+ {
+ MDblock(MDp,(Word32Type *)XX);
+ for (i=0;i<56;i++)
+ XX[i] = 0;
+ for (i=0;i<8;i++)
+ XX[56+i] = MDp->count[i];
+ MDblock(MDp,(Word32Type *)XX);
+ }
+ MDp->done = 1;
+ }
+}
+//----
41 wmsigner-2.0.2/md4.h
@@ -0,0 +1,41 @@
+#ifndef _INCLUDE_MD4
+#define _INCLUDE_MD4
+#include "stdafx.h"
+
+#ifndef _WIN32
+#define _NOT_WIN32
+#endif
+
+#if defined(__FreeBSD__) && __FreeBSD__ < 5 /* for FreeBSD version <= 4 */
+#include <inttypes.h>
+#elif defined(_NOT_WIN32)
+#include <stdint.h>
+#endif
+
+#ifdef _WIN32
+typedef DWORD Word32Type;
+#else
+typedef uint32_t Word32Type;
+#endif
+
+typedef struct {
+ Word32Type buffer[4];
+ unsigned char count[8];
+ unsigned int done;
+} MDstruct, *MDptr;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void MDbegin(MDptr MDp) ;
+
+extern void MDupdate(MDptr MDp, unsigned char *X, Word32Type count) ;
+
+extern void MDprint(MDptr MDp) ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+//---
842 wmsigner-2.0.2/rsalib1.cpp
@@ -0,0 +1,842 @@
+#include "stdafx.h"
+#ifdef _WIN32
+#ifndef _CONSOLE
+#endif
+#endif
+
+#include "rsalib1.h"
+#include <stdio.h>
+
+#ifndef WORD
+#define WORD unsigned int
+#endif
+
+int N_NEG_VAL=-1;
+
+CRSALib::CRSALib(short glob_pres)
+{
+ global_precision = glob_pres;
+ int i, j;
+ for (i=0; i< 16; i++)
+ for (j=0; j< MAX_UNIT_PRECISION; j++)
+ moduli_buf[i][j]=0;
+ moduli[0] = 0;
+ for (i=1; i<16+1; i++)
+ moduli[i] = &moduli_buf[ i-1][0];
+ for (i=0;i<16+1;i++)
+ {
+ msu_moduli[i] = 0;
+ nmsu_moduli[i] = 0;
+ }
+ for (i=0; i< 16-1; i++)
+ for (j=0; j< MAX_UNIT_PRECISION; j++)
+ mpdbuf[i][j]=0;
+
+ mpd[0] = 0;
+ for (i=1; i < 16; i++)
+ {
+ mpd[i] = &mpdbuf[ i-1][0];
+ }
+}
+
+boolean CRSALib::mp_addc(register unitptr r1,register unitptr r2,register boolean carry)
+{
+ register ulint x;
+ short precision;
+ precision = global_precision;
+
+ while (precision--)
+ {
+ x = (ulint) *r1 + (ulint) *((r2)++) + (ulint) carry;
+ *((r1)++) = (unit)x;
+ carry = ((x & ((ulint) 1 << 16)) != 0L);
+ }
+ return(carry);
+}
+
+boolean CRSALib::mp_subb(register unitptr r1,register unitptr r2,register boolean borrow)
+{
+ register ulint x;
+ short precision;
+ precision = global_precision;
+
+ while (precision--)
+ {
+ x = (ulint) *r1 - (ulint) *((r2)++) - (ulint) borrow;
+ *((r1)++) = (unit)x;
+ borrow = ((x & ((ulint) 1 << 16)) != 0L);
+ }
+ return(borrow);
+}
+
+boolean CRSALib::mp_rotate_left(register unitptr r1,register boolean carry)
+{
+ register short precision;
+ register boolean nextcarry;
+ precision = global_precision;
+
+ while (precision--)
+ {
+ nextcarry = (((signedunit) *r1) < 0);
+
+ *r1 <<= 1 ;
+ if (carry) *r1 |= 1;
+ carry = nextcarry;
+ (++(r1));
+ }
+ return(nextcarry);
+}
+
+boolean CRSALib::mp_rotate_right(register unitptr r1,register boolean carry)
+{
+ register short precision;
+ register boolean nextcarry;
+ precision = global_precision;
+ (r1) = ((r1)+(precision)-1);
+ while (precision--)
+ {
+ nextcarry = *r1 & 1;
+ *r1 >>= 1 ;
+ if (carry) *r1 |= ((unit) 0x8000);
+ carry = nextcarry;
+ (--(r1));
+ }
+ return(nextcarry);
+}
+
+short CRSALib::mp_compare(register unitptr r1,register unitptr r2)
+{
+ register short precision;
+ precision = global_precision;
+ (r1) = ((r1)+(precision)-1);
+ (r2) = ((r2)+(precision)-1);
+ do
+ {
+ if (*r1 < *r2)
+ return(-1);
+ if (*((r1)--) > *((r2)--))
+ return(1);
+ } while (--precision);
+ return(0);
+}
+
+boolean CRSALib::mp_inc(register unitptr r)
+{
+ register short precision;
+ precision = global_precision;
+
+ do
+ { if ( ++(*r) ) return(0);
+ ((r)++);
+ } while (--precision);
+ return(1);
+}
+
+boolean CRSALib::mp_dec(register unitptr r)
+{
+ register short precision;
+ precision = global_precision;
+
+ do
+ {
+ if ( (signedunit) (--(*r)) != (signedunit) -1 )
+ return(0);
+ ((r)++);
+ } while (--precision);
+ return(1);
+}
+
+void CRSALib::mp_neg(register unitptr r)
+{
+ register short precision;
+ precision = global_precision;
+
+ mp_dec(r);
+ do
+ {
+ *r = ~(*r);
+ r++;
+ } while (--precision);
+}
+
+void CRSALib::mp_move(register unitptr dst,register unitptr src)
+{
+ register short precision;
+ precision = global_precision;
+ do
+ {
+ *dst++ = *src++;
+ } while (--precision);
+}
+
+void CRSALib::mp_init(register unitptr r, word16 value)
+{
+ register short precision;
+ precision = global_precision;
+ *((r)++) = value;
+ precision--;
+ while (precision--)
+ *((r)++) = 0;
+}
+
+short CRSALib::significance(register unitptr r)
+{
+ register short precision;
+ precision = global_precision;
+ (r) = ((r)+(precision)-1);
+ do
+ {
+ if (*((r)--))
+ return(precision);
+ } while (--precision);
+ return(precision);
+}
+
+void CRSALib::unitfill0(unitptr r,word16 unitcount)
+{
+ while (unitcount--) *r++ = 0;
+}
+
+int CRSALib::mp_udiv(register unitptr remainder,register unitptr quotient,
+ register unitptr dividend,register unitptr divisor)
+{
+ int bits;
+ short dprec;
+ register unit bitmask;
+ if (( ((*(divisor))==(0)) && (significance(divisor)<=1) ))
+ return(-1);
+
+ mp_init(remainder,0);
+ mp_init(quotient,0);
+
+ {
+ dprec = significance(dividend);
+ if (!dprec) return(0);
+ bits = ((dprec) << 4);
+ (dividend) = ((dividend)+(dprec)-1);
+ bitmask = ((unit) 0x8000);
+ while (!(*(dividend) & bitmask))
+ {
+ bitmask >>= 1;
+ bits--;
+ }
+ };
+
+ (quotient) = ((quotient)+(dprec)-1);
+
+ while (bits--)
+ {
+ mp_rotate_left(remainder,(boolean)((*(dividend) & bitmask)!=0));
+ if (mp_compare(remainder,divisor) >= 0)
+ {
+ mp_subb(remainder,divisor,(boolean)0);
+ *(quotient) |= bitmask;
+ }
+ {
+ if (!(bitmask >>= 1))
+ {
+ bitmask = ((unit) 0x8000);
+ ((dividend)--); ((quotient)--);
+ }
+ };
+ }
+ return(0);
+}
+
+
+int CRSALib::mp_div(register unitptr remainder,register unitptr quotient,
+ register unitptr dividend,register unitptr divisor)
+{
+ boolean dvdsign,dsign;
+ int status;
+ dvdsign = (((signedunit) (*((dividend)+(global_precision)-1)) < 0)!=0);
+ dsign = (((signedunit) (*((divisor)+(global_precision)-1)) < 0)!=0);
+ if (dvdsign) mp_neg(dividend);
+ if (dsign) mp_neg(divisor);
+ status = mp_udiv(remainder,quotient,dividend,divisor);
+ if (dvdsign) mp_neg(dividend);
+ if (dsign) mp_neg(divisor);
+ if (status<0) return(status);
+ if (dvdsign) mp_neg(remainder);
+ if (dvdsign ^ dsign) mp_neg(quotient);
+ return(status);
+}
+
+
+word16 CRSALib::mp_shortdiv(register unitptr quotient,
+ register unitptr dividend,register word16 divisor)
+{
+ int bits;
+ short dprec;
+ register unit bitmask;
+ register word16 remainder;
+ if (!divisor)
+ return (N_NEG_VAL);
+ remainder=0;
+ mp_init(quotient,0);
+
+ {
+ dprec = significance(dividend);
+ if (!dprec) return(0);
+ bits = ((dprec) << 4);
+ (dividend) = ((dividend)+(dprec)-1);
+ bitmask = ((unit) 0x8000);
+ while (!(*(dividend) & bitmask))
+ {
+ bitmask >>= 1;
+ bits--;
+ }
+ };
+
+ (quotient) = ((quotient)+(dprec)-1);
+
+ while (bits--)
+ {
+ remainder <<= 1;
+ if ((*(dividend) & bitmask))
+ remainder++;
+ if (remainder >= divisor)
+ {
+ remainder -= divisor;
+ *(quotient) |= bitmask;
+ }
+ {
+ if (!(bitmask >>= 1))
+ {
+ bitmask = ((unit) 0x8000);
+ ((dividend)--);
+ ((quotient)--);
+ }
+ };
+ }
+ return(remainder);
+}
+
+
+int CRSALib::mp_mod(register unitptr remainder,
+ register unitptr dividend,register unitptr divisor)
+{
+ int bits;
+ short dprec;
+ register unit bitmask;
+ if (( ((*(divisor))==(0)) && (significance(divisor)<=1) ))
+ return(-1);
+ mp_init(remainder,0);
+
+ { dprec = significance(dividend);
+ if (!dprec) return(0);
+ bits = ((dprec) << 4);
+ (dividend) = ((dividend)+(dprec)-1);
+ bitmask = ((unit) 0x8000);
+ while (!(*(dividend) & bitmask))
+ {
+ bitmask >>= 1;
+ bits--;
+ }
+ };
+
+ while (bits--)
+ {
+ mp_rotate_left(remainder,(boolean)((*(dividend) & bitmask)!=0));
+ if (mp_compare(remainder,divisor) >= 0)
+ mp_subb(remainder,divisor,(boolean)0);
+ {
+ if (!(bitmask >>= 1))
+ {
+ bitmask = ((unit) 0x8000);
+ ((dividend)--);
+ }
+ };
+ }
+ return(0);
+}
+
+
+word16 CRSALib::mp_shortmod(register unitptr dividend,register word16 divisor)
+{
+ int bits;
+ short dprec;
+ register unit bitmask;
+ register word16 remainder;
+ if (!divisor)
+ return(N_NEG_VAL);
+ remainder=0;
+
+ {
+ dprec = significance(dividend);
+ if (!dprec) return(0);
+ bits = ((dprec) << 4);
+ (dividend) = ((dividend)+(dprec)-1);
+ bitmask = ((unit) 0x8000);
+ while (!(*(dividend) & bitmask))
+ {
+ bitmask >>= 1;
+ bits--;
+ }
+ };
+
+ while (bits--)
+ {
+ remainder <<= 1;
+ if ((*(dividend) & bitmask))
+ remainder++;
+ if (remainder >= divisor) remainder -= divisor;
+ {
+ if (!(bitmask >>= 1))
+ {
+ bitmask = ((unit) 0x8000); ((dividend)--);
+ }
+ };
+ }
+ return(remainder);
+}
+
+int CRSALib::mp_mult(register unitptr prod,
+ register unitptr multiplicand,register unitptr multiplier)
+{
+ int bits;
+ register unit bitmask;
+ short mprec;
+ mp_init(prod,0);
+ if (( ((*(multiplicand))==(0)) && (significance(multiplicand)<=1) ))
+ return(0);
+
+ mprec = significance(multiplier);
+ if (!mprec) return(0);
+ bits = ((mprec) << 4);
+ (multiplier) = ((multiplier)+(mprec)-1);
+ bitmask = ((unit) 0x8000);
+ while (!(*(multiplier) & bitmask))
+ {
+ bitmask >>= 1;
+ bits--;
+ }
+
+ while (bits--)
+ {
+ mp_rotate_left(prod,(boolean)0);
+ if ((*(multiplier) & bitmask))
+ {
+ mp_addc(prod,multiplicand,(boolean)0);
+ }
+ if (!(bitmask >>= 1))
+ {
+ bitmask = ((unit) 0x8000);
+ ((multiplier)--);
+ }
+ }
+ return(0);
+}
+
+void CRSALib::mp_lshift_unit(register unitptr r1)
+{
+ register short precision;
+ register unitptr r2;
+ precision = global_precision;
+ (r1) = ((r1)+(precision)-1);
+ r2 = r1;
+ while (--precision)
+ *((r1)--) = *(--(r2));
+ *r1 = 0;
+}
+
+void CRSALib::stage_mp_images(unitptr images[16],unitptr r)
+{
+ short int i;
+ images[0] = r;
+ for (i=1; i<16; i++)
+ {
+ mp_move(images[i],images[i-1]);
+ mp_rotate_left(images[i],(boolean)0);
+ }
+}
+int CRSALib::stage_merritt_modulus(unitptr n)
+{
+ short int i;
+ unitptr msu;
+ moduli[0] = n;
+
+
+ msu = ((n)+(global_precision)-1);
+ msu_moduli[0] = *((msu)--);
+ nmsu_moduli[0] = *msu;
+
+ for (i=1; i<16+1; i++)
+ {
+ mp_move(moduli[i],moduli[i-1]);
+ mp_rotate_left(moduli[i],(boolean)0);
+
+ msu = ((moduli[i])+(global_precision)-1);
+ msu_moduli[i] = *((msu)--);
+ nmsu_moduli[i] = *msu;
+ }
+ return(0);
+}
+
+int CRSALib::merritt_modmult(register unitptr prod,
+ unitptr multiplicand,register unitptr multiplier)
+{
+
+ register signedunit p_m;
+ register unitptr msu_prod;
+ register unitptr nmsu_prod;
+ short mprec;
+
+
+ stage_mp_images(mpd,multiplicand);
+
+ msu_prod = ((prod)+(global_precision)-1);
+ nmsu_prod = msu_prod;
+ ((nmsu_prod)--);
+
+ mp_init(prod,0);
+
+ mprec = significance(multiplier);
+ if (mprec==0)
+ return(0);
+ (multiplier) = ((multiplier)+(mprec)-1);
+
+ while (mprec--)
+ {
+ mp_lshift_unit(prod);
+ if (*multiplier & ((unit) 1 << (15))) mp_addc(prod,mpd[15],(boolean)0);
+ if (*multiplier & ((unit) 1 << (14))) mp_addc(prod,mpd[14],(boolean)0);
+ if (*multiplier & ((unit) 1 << (13))) mp_addc(prod,mpd[13],(boolean)0);
+ if (*multiplier & ((unit) 1 << (12))) mp_addc(prod,mpd[12],(boolean)0);
+ if (*multiplier & ((unit) 1 << (11))) mp_addc(prod,mpd[11],(boolean)0);
+ if (*multiplier & ((unit) 1 << (10))) mp_addc(prod,mpd[10],(boolean)0);
+ if (*multiplier & ((unit) 1 << (9))) mp_addc(prod,mpd[9],(boolean)0);
+ if (*multiplier & ((unit) 1 << (8))) mp_addc(prod,mpd[8],(boolean)0);
+
+ if (*multiplier & ((unit) 1 << (7))) mp_addc(prod,mpd[7],(boolean)0);
+ if (*multiplier & ((unit) 1 << (6))) mp_addc(prod,mpd[6],(boolean)0);
+ if (*multiplier & ((unit) 1 << (5))) mp_addc(prod,mpd[5],(boolean)0);
+ if (*multiplier & ((unit) 1 << (4))) mp_addc(prod,mpd[4],(boolean)0);
+ if (*multiplier & ((unit) 1 << (3))) mp_addc(prod,mpd[3],(boolean)0);
+ if (*multiplier & ((unit) 1 << (2))) mp_addc(prod,mpd[2],(boolean)0);
+ if (*multiplier & ((unit) 1 << (1))) mp_addc(prod,mpd[1],(boolean)0);
+ if (*multiplier & ((unit) 1 << (0))) mp_addc(prod,mpd[0],(boolean)0);
+
+ if (((p_m = *msu_prod-msu_moduli[16])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[16]) || ( (*nmsu_prod==nmsu_moduli[16]) && ((mp_compare(prod,moduli[16]) >= 0)) ))) ) mp_subb(prod,moduli[16],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[15])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[15]) || ( (*nmsu_prod==nmsu_moduli[15]) && ((mp_compare(prod,moduli[15]) >= 0)) ))) ) mp_subb(prod,moduli[15],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[14])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[14]) || ( (*nmsu_prod==nmsu_moduli[14]) && ((mp_compare(prod,moduli[14]) >= 0)) ))) ) mp_subb(prod,moduli[14],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[13])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[13]) || ( (*nmsu_prod==nmsu_moduli[13]) && ((mp_compare(prod,moduli[13]) >= 0)) ))) ) mp_subb(prod,moduli[13],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[12])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[12]) || ( (*nmsu_prod==nmsu_moduli[12]) && ((mp_compare(prod,moduli[12]) >= 0)) ))) ) mp_subb(prod,moduli[12],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[11])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[11]) || ( (*nmsu_prod==nmsu_moduli[11]) && ((mp_compare(prod,moduli[11]) >= 0)) ))) ) mp_subb(prod,moduli[11],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[10])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[10]) || ( (*nmsu_prod==nmsu_moduli[10]) && ((mp_compare(prod,moduli[10]) >= 0)) ))) ) mp_subb(prod,moduli[10],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[9])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[9]) || ( (*nmsu_prod==nmsu_moduli[9]) && ((mp_compare(prod,moduli[9]) >= 0)) ))) ) mp_subb(prod,moduli[9],(boolean)0);
+
+ if (((p_m = *msu_prod-msu_moduli[8])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[8]) || ( (*nmsu_prod==nmsu_moduli[8]) && ((mp_compare(prod,moduli[8]) >= 0)) ))) ) mp_subb(prod,moduli[8],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[7])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[7]) || ( (*nmsu_prod==nmsu_moduli[7]) && ((mp_compare(prod,moduli[7]) >= 0)) ))) ) mp_subb(prod,moduli[7],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[6])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[6]) || ( (*nmsu_prod==nmsu_moduli[6]) && ((mp_compare(prod,moduli[6]) >= 0)) ))) ) mp_subb(prod,moduli[6],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[5])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[5]) || ( (*nmsu_prod==nmsu_moduli[5]) && ((mp_compare(prod,moduli[5]) >= 0)) ))) ) mp_subb(prod,moduli[5],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[4])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[4]) || ( (*nmsu_prod==nmsu_moduli[4]) && ((mp_compare(prod,moduli[4]) >= 0)) ))) ) mp_subb(prod,moduli[4],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[3])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[3]) || ( (*nmsu_prod==nmsu_moduli[3]) && ((mp_compare(prod,moduli[3]) >= 0)) ))) ) mp_subb(prod,moduli[3],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[2])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[2]) || ( (*nmsu_prod==nmsu_moduli[2]) && ((mp_compare(prod,moduli[2]) >= 0)) ))) ) mp_subb(prod,moduli[2],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[1])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[1]) || ( (*nmsu_prod==nmsu_moduli[1]) && ((mp_compare(prod,moduli[1]) >= 0)) ))) ) mp_subb(prod,moduli[1],(boolean)0);
+ if (((p_m = *msu_prod-msu_moduli[0])>0) || ( (p_m==0) && ( (*nmsu_prod>nmsu_moduli[0]) || ( (*nmsu_prod==nmsu_moduli[0]) && ((mp_compare(prod,moduli[0]) >= 0)) ))) ) mp_subb(prod,moduli[0],(boolean)0);
+
+ ((multiplier)--);
+ }
+ return(0);
+}
+
+void CRSALib::merritt_burn(void)
+
+{
+ unitfill0(&(mpdbuf[0][0]),(16-1)*(MAX_UNIT_PRECISION));
+ unitfill0(&(moduli_buf[0][0]),(16)*(MAX_UNIT_PRECISION));
+ unitfill0(msu_moduli,16+1);
+ unitfill0(nmsu_moduli,16+1);
+}
+
+
+int CRSALib::countbits(unitptr r)
+{
+ int bits;
+ short prec;
+ register unit bitmask;
+ {
+ prec = significance(r);
+ if (!prec) return(0);
+ bits = ((prec) << 4);
+ (r) = ((r)+(prec)-1);
+ bitmask = ((unit) 0x8000);
+ while (!(*(r) & bitmask))
+ {
+ bitmask >>= 1; bits--;
+ }
+ };
+ return(bits);
+}
+
+
+int CRSALib::mp_modexp(register unitptr expout,register unitptr expin,
+register unitptr exponent,register unitptr modulus)
+{
+ int bits;
+ short oldprecision;
+ register unit bitmask;
+ unit product[(MAX_UNIT_PRECISION)];
+ short eprec;
+
+ mp_init(expout,1);
+ if (( ((*(exponent))==(0)) && (significance(exponent)<=1) ))
+ {
+ if (( ((*(expin))==(0)) && (significance(expin)<=1) ))
+ return(-1);
+ return(0);
+ }
+ if (( ((*(modulus))==(0)) && (significance(modulus)<=1) ))
+ return(-2);
+
+ if (((signedunit) (*((modulus)+(global_precision)-1)) < 0))
+ return(-2);
+
+ if (mp_compare(expin,modulus) >= 0)
+ return(-3);
+ if (mp_compare(exponent,modulus) >= 0)
+ return(-4);
+
+ oldprecision = global_precision;
+
+ (global_precision = ((((countbits(modulus)+(16+1))+15) >> 4)));
+
+
+ if (stage_merritt_modulus(modulus))
+ {
+ (global_precision = (oldprecision));
+ return(-5);
+ }
+ {
+ eprec = significance(exponent);
+ if (!eprec) return(0);
+ bits = ((eprec) << 4);
+ (exponent) = ((exponent)+(eprec)-1);
+ bitmask = ((unit) 0x8000);
+ while (!(*(exponent) & bitmask))
+ {
+ bitmask >>= 1;
+ bits--;
+ }
+ };
+
+ bits--;
+ mp_move(expout,expin);
+ { if (!(bitmask >>= 1)) { bitmask = ((unit) 0x8000); ((exponent)--); } };
+
+ while (bits--)
+ {
+ merritt_modmult(product,expout,expout);
+ mp_move(expout,product);
+ if ((*(exponent) & bitmask))
+ {
+ merritt_modmult(product,expout,expin);
+ mp_move(expout,product);
+ }
+ if (!(bitmask >>= 1))
+ {
+ bitmask = ((unit) 0x8000);
+ ((exponent)--);
+ }
+ }
+ mp_init(product,0);
+ merritt_burn();
+
+ (global_precision = (oldprecision));
+ return(0);
+}
+
+int CRSALib::rsa_decrypt(unitptr M, unitptr C,
+ unitptr d, unitptr p, unitptr q, unitptr u)
+{
+ unit p2[(MAX_UNIT_PRECISION)];
+ unit q2[(MAX_UNIT_PRECISION)];
+ unit temp1[(MAX_UNIT_PRECISION)];
+ unit temp2[(MAX_UNIT_PRECISION)];
+ int status;
+
+ mp_init(M,1);
+
+ if (mp_compare(p,q) >= 0)
+ {
+ unitptr t;
+ t = p; p = q; q = t;
+ }
+
+ mp_move(temp1,p);
+ mp_dec(temp1);
+ mp_mod(temp2,d,temp1);
+ mp_mod(temp1,C,p);
+ status = mp_modexp(p2,temp1,temp2,p);
+ if (status < 0)
+ return(status);
+
+ mp_move(temp1,q);
+ mp_dec(temp1);
+ mp_mod(temp2,d,temp1);
+ mp_mod(temp1,C,q);
+ status = mp_modexp(q2,temp1,temp2,q);
+ if (status < 0)
+ return(status);
+
+ if (mp_compare(p2,q2) == 0)
+ mp_move(M,p2);
+ else
+ {
+ if (mp_subb(q2,p2,(boolean)0))
+ mp_addc(q2,q,(boolean)0);
+
+ mp_mult(temp1,q2,u);
+ mp_mod(temp2,temp1,q);
+ mp_mult(temp1,p,temp2);
+ mp_addc(temp1,p2,(boolean)0);
+ mp_move(M,temp1);
+ }