From 5a9ff275c76efa18ffecfd14d55fca655db35fed Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Wed, 20 Dec 2017 11:22:17 +0300 Subject: [PATCH 1/8] Add encrypt string Add encrypt string --- deps/wrapper/include/wrapper/pki/cipher.h | 4 +- deps/wrapper/src/pki/cipher.cpp | 29 +++-- index.d.ts | 36 ++---- lib/native.ts | 18 ++- lib/pki/cipher.ts | 43 ++++++- src/node/helper.cpp | 67 ++++++++++- src/node/helper.h | 3 + src/node/pki/wcipher.cpp | 138 ++++++++++++++++------ test/cipher.js | 78 ++++++++++-- 9 files changed, 323 insertions(+), 93 deletions(-) diff --git a/deps/wrapper/include/wrapper/pki/cipher.h b/deps/wrapper/include/wrapper/pki/cipher.h index a9d2c32..d33f510 100644 --- a/deps/wrapper/include/wrapper/pki/cipher.h +++ b/deps/wrapper/include/wrapper/pki/cipher.h @@ -54,8 +54,8 @@ class Cipher{ /*Symetric or assymetric(default)*/ void setCryptoMethod(CryptoMethod::Crypto_Method method); - void encrypt(Handle inSource, Handle outEnc, DataFormat::DATA_FORMAT format); - void decrypt(Handle inEnc, Handle outDec, DataFormat::DATA_FORMAT format); + Handle encrypt(Handle inSource, Handle outEnc, DataFormat::DATA_FORMAT format); + Handle decrypt(Handle inEnc, Handle outDec, DataFormat::DATA_FORMAT format); public: Handle getAlgorithm(); diff --git a/deps/wrapper/src/pki/cipher.cpp b/deps/wrapper/src/pki/cipher.cpp index 853d6d4..b7dd0ec 100644 --- a/deps/wrapper/src/pki/cipher.cpp +++ b/deps/wrapper/src/pki/cipher.cpp @@ -87,9 +87,9 @@ void Cipher::setRecipientCert(Handle cert){ } } -void Cipher::encrypt(Handle inSource, Handle outEnc, DataFormat::DATA_FORMAT format){ +Handle Cipher::encrypt(Handle inSource, Handle outEnc, DataFormat::DATA_FORMAT format){ LOGGER_FN(); - + try{ X509 *firstRecipientCertificate = NULL; EVP_PKEY *pkey = NULL; @@ -101,7 +101,7 @@ void Cipher::encrypt(Handle inSource, Handle outEnc, DataFormat::DATA_ case CryptoMethod::SYMMETRIC: /*Check pass*/ if (hpass == NULL){ - + /*Check key*/ if (hkey == NULL){ THROW_EXCEPTION(0, Cipher, NULL, "key undefined"); @@ -120,16 +120,16 @@ void Cipher::encrypt(Handle inSource, Handle outEnc, DataFormat::DATA_ /* * We use 'benc' how cipher BIO method. * This is a filter BIO that encrypts any data written through it - */ + */ LOGGER_OPENSSL(BIO_new); if ((benc = BIO_new(BIO_f_cipher())) == NULL){ THROW_OPENSSL_EXCEPTION(0, Cipher, NULL, "BIO_new(BIO_f_cipher())"); } - + /*Save internal BIO cipher context to 'ctx'*/ LOGGER_OPENSSL(BIO_get_cipher_ctx); BIO_get_cipher_ctx(benc, &ctx); - + /*Use param '1' for encrypt*/ LOGGER_OPENSSL(EVP_CipherInit_ex); if (!EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1)) { @@ -149,7 +149,7 @@ void Cipher::encrypt(Handle inSource, Handle outEnc, DataFormat::DATA_ THROW_OPENSSL_EXCEPTION(0, Cipher, NULL, "Error write bio"); } } - + if (benc != NULL){ LOGGER_OPENSSL(BIO_push); wbio = BIO_push(benc, wbio); @@ -173,6 +173,8 @@ void Cipher::encrypt(Handle inSource, Handle outEnc, DataFormat::DATA_ THROW_EXCEPTION(0, Cipher, NULL, "bad decrypt"); } + return new Bio(wbio); + break; //**************************************************************************************** @@ -241,15 +243,16 @@ void Cipher::encrypt(Handle inSource, Handle outEnc, DataFormat::DATA_ default: THROW_EXCEPTION(0, Cipher, NULL, "Unknown crypto method"); } + return NULL; + - } catch (Handle e){ THROW_EXCEPTION(0, Cipher, e, "Error encrypt"); } } -void Cipher::decrypt(Handle inEnc, Handle outDec, DataFormat::DATA_FORMAT format){ +Handle Cipher::decrypt(Handle inEnc, Handle outDec, DataFormat::DATA_FORMAT format){ LOGGER_FN(); try{ @@ -288,7 +291,7 @@ void Cipher::decrypt(Handle inEnc, Handle outDec, DataFormat::DATA_FOR else if (memcmp(mbuf, magic, sizeof magic - 1)) { THROW_EXCEPTION(0, Cipher, NULL, "bad magic number"); } - + LOGGER_OPENSSL(EVP_BytesToKey); if (EVP_BytesToKey(cipher, dgst, salt, (unsigned char *)hpass, strlen(hpass), 1, key, iv) == 0){ THROW_OPENSSL_EXCEPTION(0, Cipher, NULL, "EVP_BytesToKey"); @@ -320,7 +323,7 @@ void Cipher::decrypt(Handle inEnc, Handle outDec, DataFormat::DATA_FOR inl = BIO_read(rbio, (char *)buff, bsize); if (inl <= 0){ break; - } + } LOGGER_OPENSSL(BIO_write); if (BIO_write(wbio, (char *)buff, inl) != inl) { THROW_EXCEPTION(0, Cipher, NULL, "Error writing output bio"); @@ -331,6 +334,7 @@ void Cipher::decrypt(Handle inEnc, Handle outDec, DataFormat::DATA_FOR if (!BIO_flush(wbio)){ THROW_EXCEPTION(0, Cipher, NULL, "bad decrypt"); } + return new Bio(wbio); break; @@ -366,7 +370,7 @@ void Cipher::decrypt(Handle inEnc, Handle outDec, DataFormat::DATA_FOR if (!CMS_decrypt_set1_pkey(cms, rkey, rcert)) { THROW_OPENSSL_EXCEPTION(0, Cipher, NULL, "CMS_decrypt_set1_pkey 'Error set private key'"); } - + LOGGER_OPENSSL(CMS_decrypt); if (!CMS_decrypt(cms, NULL, NULL, NULL, outDec->internal(), flags)) { THROW_OPENSSL_EXCEPTION(0, Cipher, NULL, "CMS_decrypt 'Error decrypt cms'"); @@ -381,6 +385,7 @@ void Cipher::decrypt(Handle inEnc, Handle outDec, DataFormat::DATA_FOR default: THROW_EXCEPTION(0, Cipher, NULL, "Unknown crypto method"); } + return NULL; } diff --git a/index.d.ts b/index.d.ts index 31bd2f3..7d178b7 100644 --- a/index.d.ts +++ b/index.d.ts @@ -186,11 +186,22 @@ declare namespace native { save(filename: string, dataFormat: trusted.DataFormat): void; getEncodedHEX(): Buffer; } + + export enum CipherContentType { + url, + buffer, + } + + export interface ICipherContent { + type: CipherContentType; + data: string | Buffer; + } + class Cipher { constructor(); setCryptoMethod(method: trusted.CryptoMethod): void; - encrypt(filenameSource: string, filenameEnc: string, format: trusted.DataFormat): void; - decrypt(filenameEnc: string, filenameDec: string, format?: trusted.DataFormat): void; + encrypt(source: ICipherContent, destinationEnc: ICipherContent, format: trusted.DataFormat): string; + decrypt(sourceEnc: ICipherContent, destinationDec: ICipherContent, format?: trusted.DataFormat): string; addRecipientsCerts(certs: CertificateCollection): void; setPrivKey(rkey: Key): void; setRecipientCert(rcert: Certificate): void; @@ -456,9 +467,6 @@ declare namespace native { isGost2012_512CSPAvailable(): boolean; checkCPCSPLicense(): boolean; getCPCSPLicense(): string; - enumProviders(): object[]; - enumContainers(type?: number): string[]; - getCertifiacteFromContainer(contName: string, provType: number, provName?: string): PKI.Certificate; } } namespace COMMON { @@ -827,24 +835,6 @@ declare namespace trusted.utils { * @memberof Csp */ static getCPCSPLicense(): string; - /** - * Enumerate available CSP - * - * @static - * @returns {object[]} {type: nuber, name: string} - * @memberof Csp - */ - static enumProviders(): object[]; - /** - * Enumerate conainers - * - * @static - * @param {number} [type] - * @returns {string[]} Fully Qualified Container Name - * @memberof Csp - */ - static enumContainers(type?: number): string[]; - static getCertifiacteFromContainer(contName: string, provType: number, provName?: string): pki.Certificate; /** * Creates an instance of Csp. * diff --git a/lib/native.ts b/lib/native.ts index 80bab64..ad63a16 100644 --- a/lib/native.ts +++ b/lib/native.ts @@ -157,11 +157,21 @@ declare namespace native { public getEncodedHEX(): Buffer; } + export enum CipherContentType { + url, + buffer, + } + + export interface ICipherContent { + type: CipherContentType; + data: string | Buffer; + } + class Cipher { constructor(); public setCryptoMethod(method: trusted.CryptoMethod): void; - public encrypt(filenameSource: string, filenameEnc: string, format: trusted.DataFormat): void; - public decrypt(filenameEnc: string, filenameDec: string, format?: trusted.DataFormat): void; + public encrypt(source: ICipherContent, destinationEnc: ICipherContent, format: trusted.DataFormat): string; + public decrypt(sourceEnc: ICipherContent, destinationDec: ICipherContent, format?: trusted.DataFormat): string; public addRecipientsCerts(certs: CertificateCollection): void; public setPrivKey(rkey: Key): void; public setRecipientCert(rcert: Certificate): void; @@ -467,10 +477,6 @@ declare namespace native { public isGost2012_512CSPAvailable(): boolean; public checkCPCSPLicense(): boolean; public getCPCSPLicense(): string; - public enumProviders(): object[]; - public enumContainers(type?: number, provName?: string): string[]; - public getCertifiacteFromContainer(contName: string, provType: number, provName?: string): PKI.Certificate; - public installCertifiacteFromContainer(contName: string, provType: number, provName?: string): void; } } diff --git a/lib/pki/cipher.ts b/lib/pki/cipher.ts index 54489d2..ab49ae9 100644 --- a/lib/pki/cipher.ts +++ b/lib/pki/cipher.ts @@ -2,6 +2,16 @@ /// namespace trusted.pki { + + export enum CipherContentType { + url, + buffer, + } + + export interface ICipherContent { + type: CipherContentType; + data: string | Buffer; + } /** * Encrypt and decrypt operations * @@ -42,8 +52,21 @@ namespace trusted.pki { * * @memberOf Cipher */ - public encrypt(filenameSource: string, filenameEnc: string, format: DataFormat): void { - this.handle.encrypt(filenameSource, filenameEnc, format); + public encrypt(source: ICipherContent, destinationEnc: ICipherContent, format: DataFormat): string { + let sourceData: any; + let destinationData: any; + + if (source.type === CipherContentType.url) + sourceData = source.data.toString(); + else + sourceData = new Buffer(source.data.valueOf() as any); + + if (destinationEnc.type === CipherContentType.url) + destinationData = destinationEnc.data.toString(); + else + destinationData = new Buffer(destinationEnc.data.valueOf() as any); + + return this.handle.encrypt(sourceData, destinationData, format); } /** @@ -55,8 +78,20 @@ namespace trusted.pki { * * @memberOf Cipher */ - public decrypt(filenameEnc: string, filenameDec: string, format?: DataFormat): void { - this.handle.decrypt(filenameEnc, filenameDec, format); + public decrypt(sourceEnc: ICipherContent, destinationDec: ICipherContent, format: DataFormat): string { + let sourceData: any; + let destinationData: any; + if (sourceEnc.type === CipherContentType.url) + sourceData = sourceEnc.data.toString(); + else + sourceData = new Buffer(sourceEnc.data.valueOf() as any); + + if (destinationDec.type === CipherContentType.url) + destinationData = destinationDec.data.toString(); + else + destinationData = new Buffer(destinationDec.data.valueOf() as any); + + return this.handle.decrypt(sourceData, destinationData, format); } /** diff --git a/src/node/helper.cpp b/src/node/helper.cpp index bac0acf..bfc7b82 100644 --- a/src/node/helper.cpp +++ b/src/node/helper.cpp @@ -100,11 +100,70 @@ DataFormat::DATA_FORMAT getCmsFileType(Handle in) { char buf[1] = { 0 }; LOGGER_OPENSSL(BIO_read); - if (in.isEmpty() || (BIO_read(in->internal(), buf, sizeof(buf)) <= 0)) { - THROW_EXCEPTION(0, NULL, NULL, "Error get CMS file type"); - } - + if (in.isEmpty() || (BIO_read(in->internal(), buf, sizeof(buf)) <= 0)) { + THROW_EXCEPTION(0, NULL, NULL, "Error get CMS file type"); + } + in->seek(0); return (0x30 == buf[0]) ? DataFormat::DER : DataFormat::BASE64; } + +std::string encBase64(const char* buf){ + std::string res = ""; + int i = 0; + while (buf[i] != NULL) + { + if ( (48 <= buf[i] && buf[i] <= 57) ||//0-9 + (65 <= buf[i] && buf[i] <= 90) ||//abc...xyz + (97 <= buf[i] && buf[i] <= 122) || //ABC...XYZ + (buf[i]=='~' || buf[i]=='!' || buf[i]=='*' || buf[i]=='(' || buf[i]==')' || buf[i]=='\'') + ) + { + res.append( &buf[i], 1); + } else { + res.append("%"); + char dig1 = (buf[i]&0xF0)>>4; + char dig2 = (buf[i]&0x0F); + if ( 0<= dig1 && dig1<= 9) dig1+=48; //0, 48 in ascii + if (10<= dig1 && dig1<=15) dig1+=97-10; //a, 97 in ascii + if ( 0<= dig2 && dig2<= 9) dig2+=48; + if (10<= dig2 && dig2<=15) dig2+=97-10; + + std::string r; + r.append( &dig1, 1); + r.append( &dig2, 1); + res.append(r);//converts char 255 to string "ff" + } + i++; + } + return res; +} + +std::string decBase64(const char* buf){ + std::string str = ""; + int i = 0; + while (buf[i] != NULL){ + str = str + (char)buf[i]; + i++; + } + std::string res = ""; + int len = str.length(); + + for (int i = 0; i < len; i++) { + int j = i ; + char ch = str.at(j); + if (ch == '%'){ + char tmpstr[] = "0x0__"; + int chnum; + tmpstr[3] = str.at(j+1); + tmpstr[4] = str.at(j+2); + chnum = strtol(tmpstr, NULL, 16); + res += chnum; + i += 2; + } else { + res += ch; + } + } + return res; +} \ No newline at end of file diff --git a/src/node/helper.h b/src/node/helper.h index 2a165a7..817904d 100644 --- a/src/node/helper.h +++ b/src/node/helper.h @@ -30,6 +30,9 @@ Handle getBuffer(v8::Local v8Value); Handle getErrorText(Handle e); DataFormat::DATA_FORMAT getCmsFileType(Handle in); +std::string encBase64(const char* buf); +std::string decBase64(const char* buf); + #define METHOD_BEGIN() \ LOGGER_FN(); diff --git a/src/node/pki/wcipher.cpp b/src/node/pki/wcipher.cpp index e5a85cf..77527b4 100644 --- a/src/node/pki/wcipher.cpp +++ b/src/node/pki/wcipher.cpp @@ -85,28 +85,63 @@ NAN_METHOD(WCipher::Encrypt) { METHOD_BEGIN(); try { - LOGGER_ARG("filenameSource"); - v8::String::Utf8Value v8FilenameSource(info[0]->ToString()); - char *filenameSource = *v8FilenameSource; - - LOGGER_ARG("filenameEnc"); - v8::String::Utf8Value v8FilenameEnc(info[1]->ToString()); - char *filenameEnc = *v8FilenameEnc; + Handle inputbuffer; + Handle outputbuffer; + + if (info[0]->IsString()){ + LOGGER_ARG("source"); + v8::String::Utf8Value v8FilenameSource(info[0]->ToString()); + BIO *pInputbuffer = BIO_new_file(*v8FilenameSource, "rb"); + if (!pInputbuffer){ + Nan::ThrowError("File not found"); + return; + } + inputbuffer = new Bio(pInputbuffer); + } else{ + LOGGER_ARG("source"); + v8::Local v8Inputbuffer = info[0]->ToObject(); + BIO *pInputbuffer = BIO_new_mem_buf(node::Buffer::Data(v8Inputbuffer), node::Buffer::Length(v8Inputbuffer)); + inputbuffer = new Bio(pInputbuffer); + } + + if (info[1]->IsString()){ + LOGGER_ARG("destinationEnc"); + v8::String::Utf8Value v8FilenameEnc(info[1]->ToString()); + BIO *pOutputbuffer = BIO_new_file(*v8FilenameEnc, "wb"); + if (!pOutputbuffer){ + Nan::ThrowError("File not found"); + return; + } + outputbuffer = new Bio(pOutputbuffer); + } + else{ + LOGGER_ARG("destinationEnc"); + BIO *pOutputbuffer = BIO_new(BIO_s_mem()); + outputbuffer = new Bio(pOutputbuffer); + } LOGGER_ARG("format"); int format = info[2]->ToNumber()->Int32Value(); - Handle inSource = NULL; - Handle outEnc = NULL; + UNWRAP_DATA(Cipher); - inSource = new Bio(BIO_TYPE_FILE, filenameSource, "rb"); - outEnc = new Bio(BIO_TYPE_FILE, filenameEnc, "wb"); + Handle encBio = _this->encrypt(inputbuffer, outputbuffer, DataFormat::get(format)); - UNWRAP_DATA(Cipher); + if (info[1]->IsString()){ + info.GetReturnValue().Set(info.This()); + } else{ + char *bptr; + long len; + len = BIO_get_mem_data(encBio->internal(), &bptr); + BIO *pOutputBio = BIO_new_mem_buf(bptr, len); + Handle outputBio = new Bio(pOutputBio); + Handle resStr = outputBio->read(); - _this->encrypt(inSource, outEnc, DataFormat::get(format)); + std::string result = encBase64(resStr->c_str()); + v8::Local v8ResStr = Nan::New(result).ToLocalChecked(); - info.GetReturnValue().Set(info.This()); + info.GetReturnValue().Set(v8ResStr); + } return; } TRY_END(); @@ -116,30 +151,63 @@ NAN_METHOD(WCipher::Decrypt) { METHOD_BEGIN(); try { - LOGGER_ARG("filenameEnc"); - v8::String::Utf8Value v8FilenameEnc(info[0]->ToString()); - char *filenameEnc = *v8FilenameEnc; - - LOGGER_ARG("filenameDec"); - v8::String::Utf8Value v8FilenameDec(info[1]->ToString()); - char *filenameDec = *v8FilenameDec; - - Handle inEnc = NULL; - Handle outDec = NULL; - - inEnc = new Bio(BIO_TYPE_FILE, filenameEnc, "rb"); - outDec = new Bio(BIO_TYPE_FILE, filenameDec, "wb"); - + Handle inputbuffer = NULL; + Handle outputbuffer; + if (info[0]->IsString()){ + LOGGER_ARG("sourceEnc"); + v8::String::Utf8Value v8FilenameSource(info[0]->ToString()); + char *filenameSource = *v8FilenameSource; + inputbuffer = new Bio(BIO_TYPE_FILE, filenameSource, "rb"); + }else{ + LOGGER_ARG("sourceEnc"); + v8::Local v8Inputbuffer = info[0]->ToObject(); + BIO *pInputbuffer1 = BIO_new_mem_buf(node::Buffer::Data(v8Inputbuffer), node::Buffer::Length(v8Inputbuffer)); + Handle inputbuffer1 = new Bio(pInputbuffer1); + Handle resStr = inputbuffer1->read(); + + std::string buffer = decBase64(resStr->c_str()); + + BIO *pInputbuffer = BIO_new_mem_buf(buffer.c_str(), buffer.length()); + inputbuffer = new Bio(pInputbuffer); + } + + if (info[1]->IsString()){ + LOGGER_ARG("destinationDec"); + v8::String::Utf8Value v8FilenameEnc(info[1]->ToString()); + char *filenameEnc = *v8FilenameEnc; + outputbuffer = new Bio(BIO_TYPE_FILE, filenameEnc, "wb"); + } + else{ + LOGGER_ARG("destinationDec"); + BIO *pOutputbuffer = BIO_new(BIO_s_mem()); + outputbuffer = new Bio(pOutputbuffer); + } + LOGGER_ARG("format"); - DataFormat::DATA_FORMAT format = (info[1]->IsUndefined() || !info[1]->IsNumber()) ? - getCmsFileType(inEnc) : - DataFormat::get(info[1]->ToNumber()->Int32Value()); + DataFormat::DATA_FORMAT format; + if (info[0]->IsString()){ + format = (info[1]->IsUndefined() || !info[1]->IsNumber()) ? getCmsFileType(inputbuffer) : DataFormat::get(info[1]->ToNumber()->Int32Value()); + } else { + format = DataFormat::BASE64; + } UNWRAP_DATA(Cipher); - - _this->decrypt(inEnc, outDec, format); - - info.GetReturnValue().Set(info.This()); + + Handle result = _this->decrypt(inputbuffer, outputbuffer, format); + + if (info[1]->IsString()){ + info.GetReturnValue().Set(info.This()); + } else { + char *bptr; + long len; + len = BIO_get_mem_data(result->internal(), &bptr); + BIO *outputQwerty = BIO_new_mem_buf(bptr, len); + Handle outputScrin = new Bio(outputQwerty); + Handle resStr = outputScrin->read(); + + v8::Local v8ResStr = Nan::New(resStr->c_str()).ToLocalChecked(); + info.GetReturnValue().Set(v8ResStr); + } return; } TRY_END(); diff --git a/test/cipher.js b/test/cipher.js index 625a04f..b6e6f6f 100644 --- a/test/cipher.js +++ b/test/cipher.js @@ -30,17 +30,64 @@ describe("CipherSYMMETRIC", function() { it("encrypt", function() { cipher.digest = "MD5"; cipher.password = "4321"; - cipher.encrypt(DEFAULT_RESOURCES_PATH + "/test.txt", DEFAULT_OUT_PATH + "/encSym.txt"); + var inp = { + type: trusted.pki.CipherContentType.url, + data: DEFAULT_RESOURCES_PATH + "/test.txt" + }; + var outp = { + type: trusted.pki.CipherContentType.url, + data: DEFAULT_OUT_PATH + "/encSym.txt" + }; + cipher.encrypt(inp, outp); }); it("decrypt", function() { - cipher.decrypt(DEFAULT_OUT_PATH + "/encSym.txt", DEFAULT_OUT_PATH + "/decSym.txt"); + var inp = { + type: trusted.pki.CipherContentType.url, + data: DEFAULT_OUT_PATH + "/encSym.txt" + }; + var outp = { + type: trusted.pki.CipherContentType.url, + data: DEFAULT_OUT_PATH + "/decSym.txt" + }; + cipher.decrypt(inp, outp); var res = fs.readFileSync(DEFAULT_RESOURCES_PATH + "/test.txt"); var out = fs.readFileSync(DEFAULT_OUT_PATH + "/decSym.txt"); assert.equal(res.toString() === out.toString(), true, "Resource and decrypt file diff"); }); + + var encStr; + var inputStr = "Text Текст 1234 !@#$%^&*()_+?"; + it("encrypt string", function() { + encStr = ""; + cipher.digest = "MD5"; + cipher.password = "4321"; + var inp = { + type: trusted.pki.CipherContentType.buffer, + data: inputStr + }; + var outp = { + type: trusted.pki.CipherContentType.buffer, + data: "" + }; + encStr = cipher.encrypt(inp, outp); + }); + + it("decrypt string", function() { + var inp = { + type: trusted.pki.CipherContentType.buffer, + data: encStr + }; + var outp = { + type: trusted.pki.CipherContentType.buffer, + data: "" + }; + var decStr = cipher.decrypt(inp, outp); + + assert.equal(inputStr === decStr, true, "Resource and decrypt text diff"); + }); }); describe("CipherASSYMETRIC", function() { @@ -66,7 +113,15 @@ describe("CipherASSYMETRIC", function() { }); it("encrypt", function() { - cipher.encrypt(DEFAULT_RESOURCES_PATH + "/test.txt", DEFAULT_OUT_PATH + "/encAssym.txt", trusted.DataFormat.PEM); + var inp = { + type: trusted.pki.CipherContentType.url, + data: DEFAULT_RESOURCES_PATH + "/test.txt" + }; + var outp = { + type: trusted.pki.CipherContentType.url, + data: DEFAULT_OUT_PATH + "/encAssym.txt" + }; + cipher.encrypt(inp, outp, trusted.DataFormat.PEM); }); it("recipient cert", function() { @@ -90,7 +145,7 @@ describe("CipherASSYMETRIC", function() { ris = cipher.getRecipientInfos(DEFAULT_OUT_PATH + "/encAssym.txt", trusted.DataFormat.PEM); assert.equal(ris.length, 2, "Recipients length 2"); - ri = ris.items(0); + ri = ris.items(1); if (ri.serialNumber === "FD7CF8FC52A1D181") { assert.equal(ri.issuerName, "/2.5.4.6=RU/2.5.4.8=Mari El/2.5.4.7=Yoshkar-Ola/2.5.4.10=Cifrovie Tehnologii/2.5.4.3=Test certificate/1.2.840.113549.1.9.1= trusted@digt.ru", "Error issuer name"); assert.equal(ri.serialNumber, "FD7CF8FC52A1D181", "Error serial number"); @@ -103,7 +158,7 @@ describe("CipherASSYMETRIC", function() { assert.equal(ri.ktriCertCmp(trusted.pki.Certificate.load(DEFAULT_RESOURCES_PATH + "/test.crt", trusted.DataFormat.DER)) === 0, true, "Compare recipient cert"); } - ri = ris.items(1); + ri = ris.items(0); assert.equal(typeof (ri.issuerName), "string", "Error issuer name"); assert.equal(typeof (ri.serialNumber), "string", "Error serial number"); }); @@ -115,7 +170,7 @@ describe("CipherASSYMETRIC", function() { for (var j = 0; j < ris.length; j++) { ri = ris.items(j); - if (ri.issuerName === "/2.5.4.6=RU/2.5.4.8=Mari El/2.5.4.7=Yoshkar-Ola/2.5.4.10=Cifrovie Tehnologii/2.5.4.3=Test certificate/1.2.840.113549.1.9.1= trusted@digt.ru") { + if (ri.issuerName === "/2.5.4.6=IL/2.5.4.10=StartCom Ltd./2.5.4.11=Secure Digital Certificate Signing/2.5.4.3=StartCom Certification Authority", "Error issuer name") { break; } } @@ -169,7 +224,16 @@ describe("CipherASSYMETRIC", function() { cipher.recipientCert = cert; cipher.privKey = store.getItem(key); - cipher.decrypt(DEFAULT_OUT_PATH + "/encAssym.txt", DEFAULT_OUT_PATH + "/decAssym.txt", trusted.DataFormat.PEM); + var inp = { + type: trusted.pki.CipherContentType.url, + data: DEFAULT_OUT_PATH + "/encAssym.txt" + }; + var outp = { + type: trusted.pki.CipherContentType.url, + data: DEFAULT_OUT_PATH + "/decAssym.txt" + }; + + cipher.decrypt(inp, outp, trusted.DataFormat.PEM); var res = fs.readFileSync(DEFAULT_RESOURCES_PATH + "/test.txt"); var out = fs.readFileSync(DEFAULT_OUT_PATH + "/decAssym.txt"); From 829ebe8d41d8ba907c4e3c002afa3fe30453b1f9 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Wed, 20 Dec 2017 11:44:03 +0300 Subject: [PATCH 2/8] fix test --- test/cipher.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/cipher.js b/test/cipher.js index b6e6f6f..ed54693 100644 --- a/test/cipher.js +++ b/test/cipher.js @@ -145,7 +145,7 @@ describe("CipherASSYMETRIC", function() { ris = cipher.getRecipientInfos(DEFAULT_OUT_PATH + "/encAssym.txt", trusted.DataFormat.PEM); assert.equal(ris.length, 2, "Recipients length 2"); - ri = ris.items(1); + ri = ris.items(0); if (ri.serialNumber === "FD7CF8FC52A1D181") { assert.equal(ri.issuerName, "/2.5.4.6=RU/2.5.4.8=Mari El/2.5.4.7=Yoshkar-Ola/2.5.4.10=Cifrovie Tehnologii/2.5.4.3=Test certificate/1.2.840.113549.1.9.1= trusted@digt.ru", "Error issuer name"); assert.equal(ri.serialNumber, "FD7CF8FC52A1D181", "Error serial number"); @@ -158,7 +158,7 @@ describe("CipherASSYMETRIC", function() { assert.equal(ri.ktriCertCmp(trusted.pki.Certificate.load(DEFAULT_RESOURCES_PATH + "/test.crt", trusted.DataFormat.DER)) === 0, true, "Compare recipient cert"); } - ri = ris.items(0); + ri = ris.items(1); assert.equal(typeof (ri.issuerName), "string", "Error issuer name"); assert.equal(typeof (ri.serialNumber), "string", "Error serial number"); }); @@ -170,7 +170,7 @@ describe("CipherASSYMETRIC", function() { for (var j = 0; j < ris.length; j++) { ri = ris.items(j); - if (ri.issuerName === "/2.5.4.6=IL/2.5.4.10=StartCom Ltd./2.5.4.11=Secure Digital Certificate Signing/2.5.4.3=StartCom Certification Authority", "Error issuer name") { + if (ri.issuerName === "/2.5.4.6=RU/2.5.4.8=Mari El/2.5.4.7=Yoshkar-Ola/2.5.4.10=Cifrovie Tehnologii/2.5.4.3=Test certificate/1.2.840.113549.1.9.1= trusted@digt.ru", "Error issuer name") { break; } } From 72cb7cd5bbbde08127a2bb9aa8b8082a8662c4e4 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Wed, 20 Dec 2017 11:47:18 +0300 Subject: [PATCH 3/8] fix test --- test/cipher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cipher.js b/test/cipher.js index ed54693..9b9a85a 100644 --- a/test/cipher.js +++ b/test/cipher.js @@ -170,7 +170,7 @@ describe("CipherASSYMETRIC", function() { for (var j = 0; j < ris.length; j++) { ri = ris.items(j); - if (ri.issuerName === "/2.5.4.6=RU/2.5.4.8=Mari El/2.5.4.7=Yoshkar-Ola/2.5.4.10=Cifrovie Tehnologii/2.5.4.3=Test certificate/1.2.840.113549.1.9.1= trusted@digt.ru", "Error issuer name") { + if (ri.issuerName === "/2.5.4.6=RU/2.5.4.8=Mari El/2.5.4.7=Yoshkar-Ola/2.5.4.10=Cifrovie Tehnologii/2.5.4.3=Test certificate/1.2.840.113549.1.9.1= trusted@digt.ru") { break; } } From c2edcad71726e67231fcfa8b03057a3db8f125f1 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Thu, 21 Dec 2017 14:26:05 +0300 Subject: [PATCH 4/8] Add encrypt string --- lib/native.ts | 8 ++++++-- lib/pki/cipher.ts | 36 ++++++++++++++++++------------------ src/node/pki/wcipher.cpp | 7 ++++--- test/cipher.js | 9 +++++++-- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/lib/native.ts b/lib/native.ts index ad63a16..fd9302a 100644 --- a/lib/native.ts +++ b/lib/native.ts @@ -161,7 +161,7 @@ declare namespace native { url, buffer, } - + export interface ICipherContent { type: CipherContentType; data: string | Buffer; @@ -171,7 +171,7 @@ declare namespace native { constructor(); public setCryptoMethod(method: trusted.CryptoMethod): void; public encrypt(source: ICipherContent, destinationEnc: ICipherContent, format: trusted.DataFormat): string; - public decrypt(sourceEnc: ICipherContent, destinationDec: ICipherContent, format?: trusted.DataFormat): string; + public decrypt(sourceEnc: ICipherContent, destDec: ICipherContent, format?: trusted.DataFormat): string; public addRecipientsCerts(certs: CertificateCollection): void; public setPrivKey(rkey: Key): void; public setRecipientCert(rcert: Certificate): void; @@ -477,6 +477,10 @@ declare namespace native { public isGost2012_512CSPAvailable(): boolean; public checkCPCSPLicense(): boolean; public getCPCSPLicense(): string; + public enumProviders(): object[]; + public enumContainers(type?: number, provName?: string): string[]; + public getCertifiacteFromContainer(contName: string, provType: number, provName?: string): PKI.Certificate; + public installCertifiacteFromContainer(contName: string, provType: number, provName?: string): void; } } diff --git a/lib/pki/cipher.ts b/lib/pki/cipher.ts index ab49ae9..d329d15 100644 --- a/lib/pki/cipher.ts +++ b/lib/pki/cipher.ts @@ -56,16 +56,16 @@ namespace trusted.pki { let sourceData: any; let destinationData: any; - if (source.type === CipherContentType.url) - sourceData = source.data.toString(); - else - sourceData = new Buffer(source.data.valueOf() as any); - - if (destinationEnc.type === CipherContentType.url) + if (source.type === CipherContentType.url) { + sourceData = source.data.toString(); + } else { + sourceData = new Buffer(source.data.valueOf() as any); + } + if (destinationEnc.type === CipherContentType.url) { destinationData = destinationEnc.data.toString(); - else - destinationData = new Buffer(destinationEnc.data.valueOf() as any); - + } else { + destinationData = new Buffer(destinationEnc.data.valueOf() as any); + } return this.handle.encrypt(sourceData, destinationData, format); } @@ -78,19 +78,19 @@ namespace trusted.pki { * * @memberOf Cipher */ - public decrypt(sourceEnc: ICipherContent, destinationDec: ICipherContent, format: DataFormat): string { + public decrypt(sourceEnc: ICipherContent, destDec: ICipherContent, format: DataFormat): string { let sourceData: any; let destinationData: any; - if (sourceEnc.type === CipherContentType.url) + if (sourceEnc.type === CipherContentType.url) { sourceData = sourceEnc.data.toString(); - else + } else { sourceData = new Buffer(sourceEnc.data.valueOf() as any); - - if (destinationDec.type === CipherContentType.url) - destinationData = destinationDec.data.toString(); - else - destinationData = new Buffer(destinationDec.data.valueOf() as any); - + } + if (destDec.type === CipherContentType.url) { + destinationData = destDec.data.toString(); + } else { + destinationData = new Buffer(destDec.data.valueOf() as any); + } return this.handle.decrypt(sourceData, destinationData, format); } diff --git a/src/node/pki/wcipher.cpp b/src/node/pki/wcipher.cpp index 77527b4..b7a6f60 100644 --- a/src/node/pki/wcipher.cpp +++ b/src/node/pki/wcipher.cpp @@ -151,8 +151,9 @@ NAN_METHOD(WCipher::Decrypt) { METHOD_BEGIN(); try { - Handle inputbuffer = NULL; + Handle inputbuffer; Handle outputbuffer; + if (info[0]->IsString()){ LOGGER_ARG("sourceEnc"); v8::String::Utf8Value v8FilenameSource(info[0]->ToString()); @@ -172,13 +173,13 @@ NAN_METHOD(WCipher::Decrypt) { } if (info[1]->IsString()){ - LOGGER_ARG("destinationDec"); + LOGGER_ARG("destDec"); v8::String::Utf8Value v8FilenameEnc(info[1]->ToString()); char *filenameEnc = *v8FilenameEnc; outputbuffer = new Bio(BIO_TYPE_FILE, filenameEnc, "wb"); } else{ - LOGGER_ARG("destinationDec"); + LOGGER_ARG("destDec"); BIO *pOutputbuffer = BIO_new(BIO_s_mem()); outputbuffer = new Bio(pOutputbuffer); } diff --git a/test/cipher.js b/test/cipher.js index 9b9a85a..4b78a0f 100644 --- a/test/cipher.js +++ b/test/cipher.js @@ -38,6 +38,7 @@ describe("CipherSYMMETRIC", function() { type: trusted.pki.CipherContentType.url, data: DEFAULT_OUT_PATH + "/encSym.txt" }; + cipher.encrypt(inp, outp); }); @@ -50,6 +51,7 @@ describe("CipherSYMMETRIC", function() { type: trusted.pki.CipherContentType.url, data: DEFAULT_OUT_PATH + "/decSym.txt" }; + cipher.decrypt(inp, outp); var res = fs.readFileSync(DEFAULT_RESOURCES_PATH + "/test.txt"); @@ -60,6 +62,7 @@ describe("CipherSYMMETRIC", function() { var encStr; var inputStr = "Text Текст 1234 !@#$%^&*()_+?"; + it("encrypt string", function() { encStr = ""; cipher.digest = "MD5"; @@ -70,8 +73,9 @@ describe("CipherSYMMETRIC", function() { }; var outp = { type: trusted.pki.CipherContentType.buffer, - data: "" + data: "test/out/encSym.txt" }; + encStr = cipher.encrypt(inp, outp); }); @@ -82,7 +86,7 @@ describe("CipherSYMMETRIC", function() { }; var outp = { type: trusted.pki.CipherContentType.buffer, - data: "" + data: "test/out/decSym.txt" }; var decStr = cipher.decrypt(inp, outp); @@ -121,6 +125,7 @@ describe("CipherASSYMETRIC", function() { type: trusted.pki.CipherContentType.url, data: DEFAULT_OUT_PATH + "/encAssym.txt" }; + cipher.encrypt(inp, outp, trusted.DataFormat.PEM); }); From b63293918d11e01b32c461bec9b80189536b1a80 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Thu, 21 Dec 2017 15:13:57 +0300 Subject: [PATCH 5/8] Add encrypt string --- test/cipher.js | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/test/cipher.js b/test/cipher.js index 4b78a0f..fbf8180 100644 --- a/test/cipher.js +++ b/test/cipher.js @@ -60,35 +60,32 @@ describe("CipherSYMMETRIC", function() { assert.equal(res.toString() === out.toString(), true, "Resource and decrypt file diff"); }); - var encStr; - var inputStr = "Text Текст 1234 !@#$%^&*()_+?"; + it("encrypt && decrypt string", function() { + var inputStr = "Text Текст 1234 !@#$%^&*()_+?"; - it("encrypt string", function() { - encStr = ""; cipher.digest = "MD5"; cipher.password = "4321"; - var inp = { + var inpEnc = { type: trusted.pki.CipherContentType.buffer, data: inputStr }; - var outp = { + var outpEnc = { type: trusted.pki.CipherContentType.buffer, - data: "test/out/encSym.txt" + data: "" }; - encStr = cipher.encrypt(inp, outp); - }); + var encStr = cipher.encrypt(inpEnc, outpEnc); - it("decrypt string", function() { - var inp = { + var inpDec = { type: trusted.pki.CipherContentType.buffer, data: encStr }; - var outp = { + var outpDec = { type: trusted.pki.CipherContentType.buffer, - data: "test/out/decSym.txt" + data: "" }; - var decStr = cipher.decrypt(inp, outp); + + var decStr = cipher.decrypt(inpDec, outpDec); assert.equal(inputStr === decStr, true, "Resource and decrypt text diff"); }); @@ -246,3 +243,4 @@ describe("CipherASSYMETRIC", function() { assert.equal(res.toString() === out.toString(), true, "Resource and decrypt file diff"); }); }); + From 8f699f0b0de2ccea10fd45a8be0b13653758bfee Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Thu, 21 Dec 2017 16:00:10 +0300 Subject: [PATCH 6/8] Add encrypt string --- src/node/pki/wcipher.cpp | 20 +++++++++----------- test/cipher.js | 11 +++++++---- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/node/pki/wcipher.cpp b/src/node/pki/wcipher.cpp index b7a6f60..26d3e0f 100644 --- a/src/node/pki/wcipher.cpp +++ b/src/node/pki/wcipher.cpp @@ -85,8 +85,8 @@ NAN_METHOD(WCipher::Encrypt) { METHOD_BEGIN(); try { - Handle inputbuffer; - Handle outputbuffer; + Handle inputbuffer = NULL; + Handle outputbuffer = NULL; if (info[0]->IsString()){ LOGGER_ARG("source"); @@ -130,8 +130,8 @@ NAN_METHOD(WCipher::Encrypt) { if (info[1]->IsString()){ info.GetReturnValue().Set(info.This()); } else{ - char *bptr; - long len; + char *bptr = NULL; + long len = 0; len = BIO_get_mem_data(encBio->internal(), &bptr); BIO *pOutputBio = BIO_new_mem_buf(bptr, len); Handle outputBio = new Bio(pOutputBio); @@ -151,8 +151,8 @@ NAN_METHOD(WCipher::Decrypt) { METHOD_BEGIN(); try { - Handle inputbuffer; - Handle outputbuffer; + Handle inputbuffer = NULL; + Handle outputbuffer = NULL; if (info[0]->IsString()){ LOGGER_ARG("sourceEnc"); @@ -186,11 +186,9 @@ NAN_METHOD(WCipher::Decrypt) { LOGGER_ARG("format"); - DataFormat::DATA_FORMAT format; + DataFormat::DATA_FORMAT format = DataFormat::BASE64; if (info[0]->IsString()){ format = (info[1]->IsUndefined() || !info[1]->IsNumber()) ? getCmsFileType(inputbuffer) : DataFormat::get(info[1]->ToNumber()->Int32Value()); - } else { - format = DataFormat::BASE64; } UNWRAP_DATA(Cipher); @@ -199,8 +197,8 @@ NAN_METHOD(WCipher::Decrypt) { if (info[1]->IsString()){ info.GetReturnValue().Set(info.This()); } else { - char *bptr; - long len; + char *bptr = NULL; + long len = 0; len = BIO_get_mem_data(result->internal(), &bptr); BIO *outputQwerty = BIO_new_mem_buf(bptr, len); Handle outputScrin = new Bio(outputQwerty); diff --git a/test/cipher.js b/test/cipher.js index fbf8180..12311e7 100644 --- a/test/cipher.js +++ b/test/cipher.js @@ -60,9 +60,9 @@ describe("CipherSYMMETRIC", function() { assert.equal(res.toString() === out.toString(), true, "Resource and decrypt file diff"); }); - it("encrypt && decrypt string", function() { - var inputStr = "Text Текст 1234 !@#$%^&*()_+?"; + var inputStr = "Text Текст 1234 !@#$%^&*()_+?"; + it("encrypt string", function() { cipher.digest = "MD5"; cipher.password = "4321"; var inpEnc = { @@ -74,11 +74,14 @@ describe("CipherSYMMETRIC", function() { data: "" }; - var encStr = cipher.encrypt(inpEnc, outpEnc); + cipher.encrypt(inpEnc, outpEnc); + }); + it("decrypt string", function() { var inpDec = { type: trusted.pki.CipherContentType.buffer, - data: encStr + data: "Salted%5f%5f%5cua%91V%fb%db%1c8A%a3%85%5cb~%cf%7d%b7%13%91%a4k%cc%5c%86Q%d5%" + + "d2%d62%9a%f8%8eo%7dk%13%a9%3c%f80%fd%88%f8%1b4%91A" }; var outpDec = { type: trusted.pki.CipherContentType.buffer, From 65df0adfb3297a8ce85d5d3b96824a56a1370a29 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Fri, 22 Dec 2017 11:55:20 +0300 Subject: [PATCH 7/8] Add encrypt string --- src/node/pki/wcipher.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/node/pki/wcipher.cpp b/src/node/pki/wcipher.cpp index 26d3e0f..1ba6190 100644 --- a/src/node/pki/wcipher.cpp +++ b/src/node/pki/wcipher.cpp @@ -153,6 +153,7 @@ NAN_METHOD(WCipher::Decrypt) { try { Handle inputbuffer = NULL; Handle outputbuffer = NULL; + std::string buffer; if (info[0]->IsString()){ LOGGER_ARG("sourceEnc"); @@ -166,7 +167,7 @@ NAN_METHOD(WCipher::Decrypt) { Handle inputbuffer1 = new Bio(pInputbuffer1); Handle resStr = inputbuffer1->read(); - std::string buffer = decBase64(resStr->c_str()); + buffer = decBase64(resStr->c_str()); BIO *pInputbuffer = BIO_new_mem_buf(buffer.c_str(), buffer.length()); inputbuffer = new Bio(pInputbuffer); From 46254336a8ca404df0a03df42320cb285ae5f58d Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Mon, 25 Dec 2017 16:22:27 +0300 Subject: [PATCH 8/8] Show version CSP --- deps/wrapper/include/wrapper/utils/csp.h | 2 + deps/wrapper/src/utils/csp.cpp | 53 ++++++++++++++++++++++++ index.d.ts | 2 + lib/native.ts | 1 + lib/utils/csp.ts | 13 ++++++ src/node/utils/wcsp.cpp | 18 ++++++++ src/node/utils/wcsp.h | 2 + 7 files changed, 91 insertions(+) diff --git a/deps/wrapper/include/wrapper/utils/csp.h b/deps/wrapper/include/wrapper/utils/csp.h index a58268a..3a5fc9c 100644 --- a/deps/wrapper/include/wrapper/utils/csp.h +++ b/deps/wrapper/include/wrapper/utils/csp.h @@ -23,6 +23,8 @@ class Csp { bool checkCPCSPLicense(); Handle getCPCSPLicense(); + Handle getCPCSPVersion(); + std::vector enumProviders(); std::vector> enumContainers(int provType, Handle provName); Handle getCertifiacteFromContainer(Handle contName, int provType, Handle provName); diff --git a/deps/wrapper/src/utils/csp.cpp b/deps/wrapper/src/utils/csp.cpp index 4051e34..18b0e48 100644 --- a/deps/wrapper/src/utils/csp.cpp +++ b/deps/wrapper/src/utils/csp.cpp @@ -1,6 +1,7 @@ #include "../stdafx.h" #include "wrapper/utils/csp.h" +#include bool Csp::isGost2001CSPAvailable() { LOGGER_FN(); @@ -236,6 +237,58 @@ Handle Csp::getCPCSPLicense() { } } +Handle Csp::getCPCSPVersion() { + LOGGER_FN(); + + try { +#ifdef CSP_ENABLE + static HCRYPTPROV hCryptProv = 0; + Handle version; + DWORD dwVersion[100]; + DWORD dwDataLength = (DWORD)sizeof(dwVersion); + + if (!isGost2001CSPAvailable()) { + THROW_EXCEPTION(0, Key, NULL, "GOST 2001 provaider not available"); + } + + if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT)){ + THROW_EXCEPTION(0, Csp, NULL, "CryptAcquireContext. Error: 0x%08x", GetLastError()); + } + + if (!CryptGetProvParam(hCryptProv, PP_VERSION_EX, (BYTE*)&dwVersion, &dwDataLength, 0)){ + THROW_EXCEPTION(0, Key, NULL, "CryptGetProvParam. Error: 0x%08x", GetLastError()); + } + + std::string str = ""; + for (int i = 3; i >= 0; i--){ + if (i == 1) continue; + std::stringstream ss; + ss << dwVersion[i]; + if (i == 0) + str = str + ss.str(); + else + str = str + ss.str() + "."; + } + version = new std::string(str); + + if (hCryptProv) { + if (!CryptReleaseContext(hCryptProv, 0)) { + THROW_EXCEPTION(0, Csp, NULL, "CryptReleaseContext. Error: 0x%08x", GetLastError()); + } + } + + hCryptProv = 0; + + return version; +#else + THROW_EXCEPTION(0, Csp, NULL, "Only if defined CSP_ENABLE"); +#endif + } + catch (Handle e){ + THROW_EXCEPTION(0, Csp, e, "Error get cpcsp version"); + } +} + std::vector Csp::enumProviders() { LOGGER_FN(); diff --git a/index.d.ts b/index.d.ts index 7d178b7..3f79aad 100644 --- a/index.d.ts +++ b/index.d.ts @@ -835,6 +835,8 @@ declare namespace trusted.utils { * @memberof Csp */ static getCPCSPLicense(): string; + + static getCPCSPVersion(): string; /** * Creates an instance of Csp. * diff --git a/lib/native.ts b/lib/native.ts index fd9302a..61dc26f 100644 --- a/lib/native.ts +++ b/lib/native.ts @@ -477,6 +477,7 @@ declare namespace native { public isGost2012_512CSPAvailable(): boolean; public checkCPCSPLicense(): boolean; public getCPCSPLicense(): string; + public getCPCSPVersion(): string; public enumProviders(): object[]; public enumContainers(type?: number, provName?: string): string[]; public getCertifiacteFromContainer(contName: string, provType: number, provName?: string): PKI.Certificate; diff --git a/lib/utils/csp.ts b/lib/utils/csp.ts index 3e734f9..e0cf9f7 100644 --- a/lib/utils/csp.ts +++ b/lib/utils/csp.ts @@ -73,6 +73,19 @@ namespace trusted.utils { return csp.getCPCSPLicense(); } + /** + * Return instaled correct license for CryptoPro CSP + * Throw exception if provaider not available + * + * @static + * @returns {boolean} + * @memberof Csp + */ + public static getCPCSPVersion(): string { + const csp = new native.UTILS.Csp(); + return csp.getCPCSPVersion(); + } + /** * Enumerate available CSP * diff --git a/src/node/utils/wcsp.cpp b/src/node/utils/wcsp.cpp index 0b276ff..50746d8 100644 --- a/src/node/utils/wcsp.cpp +++ b/src/node/utils/wcsp.cpp @@ -22,6 +22,8 @@ void WCsp::Init(v8::Handle exports) { Nan::SetPrototypeMethod(tpl, "checkCPCSPLicense", CheckCPCSPLicense); Nan::SetPrototypeMethod(tpl, "getCPCSPLicense", GetCPCSPLicense); + Nan::SetPrototypeMethod(tpl, "getCPCSPVersion", GetCPCSPVersion); + Nan::SetPrototypeMethod(tpl, "enumProviders", EnumProviders); Nan::SetPrototypeMethod(tpl, "enumContainers", EnumContainers); Nan::SetPrototypeMethod(tpl, "getCertifiacteFromContainer", GetCertifiacteFromContainer); @@ -120,6 +122,22 @@ NAN_METHOD(WCsp::GetCPCSPLicense) { TRY_END(); } +NAN_METHOD(WCsp::GetCPCSPVersion) { + METHOD_BEGIN(); + + try { + UNWRAP_DATA(Csp); + + Handle lic = _this->getCPCSPVersion(); + + v8::Local v8Lic = Nan::New(lic->c_str()).ToLocalChecked(); + + info.GetReturnValue().Set(v8Lic); + return; + } + TRY_END(); +} + NAN_METHOD(WCsp::EnumProviders) { METHOD_BEGIN(); diff --git a/src/node/utils/wcsp.h b/src/node/utils/wcsp.h index 1cd450c..4e672b0 100644 --- a/src/node/utils/wcsp.h +++ b/src/node/utils/wcsp.h @@ -21,6 +21,8 @@ WRAP_CLASS(Csp){ static NAN_METHOD(CheckCPCSPLicense); static NAN_METHOD(GetCPCSPLicense); + + static NAN_METHOD(GetCPCSPVersion); static NAN_METHOD(EnumProviders); static NAN_METHOD(EnumContainers);