Created
November 20, 2018 13:58
-
-
Save nosalvage/621b8ba7cdf088a7de8021f6a713863c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CSPManager.m | |
// Faktorin | |
// | |
// Created by Peter Litvinov on 10/18/18. | |
// Copyright © 2018 Facebook. All rights reserved. | |
// | |
#import "CSPManager.h" | |
#import <React/RCTLog.h> | |
#import "NSData+Base64.h" | |
#import <CPROCSP/CPROCSP.h> | |
#import <CPROCSP/DisableIntegrity.h> | |
#include <stdio.h> | |
#pragma comment (lib, "Crypt32") | |
#define CERT_STORE_NAME L"MY" | |
#define MY_ENCODING_TYPE X509_ASN_ENCODING | |
#define SIGNER_NAME L"PeterLitvinov" | |
void MyHandleError(LPTSTR psz) | |
{ | |
_ftprintf(stderr, TEXT("An error occurred in the program. \n")); | |
_ftprintf(stderr, TEXT("%s\n"), psz); | |
_ftprintf(stderr, TEXT("Error number %x.\n")); | |
_ftprintf(stderr, TEXT("Program terminating. \n")); | |
} | |
@implementation CSPManager | |
//HCERTSTORE | |
RCT_EXPORT_MODULE(); | |
//bool VerifySignedMessage( | |
// CRYPT_DATA_BLOB *pSignedMessageBlob, | |
// CRYPT_DATA_BLOB *pDecodedMessageBlob) | |
//{ | |
// bool fReturn = false; | |
// DWORD cbDecodedMessageBlob; | |
// BYTE *pbDecodedMessageBlob = NULL; | |
// CRYPT_VERIFY_MESSAGE_PARA VerifyParams; | |
// | |
// // Initialize the output. | |
// pDecodedMessageBlob->cbData = 0; | |
// pDecodedMessageBlob->pbData = NULL; | |
// | |
// // Initialize the VerifyParams data structure. | |
// VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA); | |
// VerifyParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE; | |
// VerifyParams.hCryptProv = 0; | |
// VerifyParams.pfnGetSignerCertificate = NULL; | |
// VerifyParams.pvGetArg = NULL; | |
// | |
// // First, call CryptVerifyMessageSignature to get the length | |
// // of the buffer needed to hold the decoded message. | |
// if(CryptVerifyMessageSignature( | |
// &VerifyParams, | |
// 0, | |
// pSignedMessageBlob->pbData, | |
// pSignedMessageBlob->cbData, | |
// NULL, | |
// &cbDecodedMessageBlob, | |
// NULL)) | |
// { | |
// _tprintf(TEXT("%d bytes needed for the decoded message.\n"), | |
// cbDecodedMessageBlob); | |
// | |
// } | |
// else | |
// { | |
// _tprintf(TEXT("Verification message failed. \n")); | |
// goto exit_VerifySignedMessage; | |
// } | |
// | |
// //--------------------------------------------------------------- | |
// // Allocate memory for the decoded message. | |
// if(!(pbDecodedMessageBlob = | |
// (BYTE*)malloc(cbDecodedMessageBlob))) | |
// { | |
// MyHandleError( | |
// TEXT("Memory allocation error allocating decode BLOB.")); | |
// goto exit_VerifySignedMessage; | |
// } | |
// | |
// //--------------------------------------------------------------- | |
// // Call CryptVerifyMessageSignature again to verify the signature | |
// // and, if successful, copy the decoded message into the buffer. | |
// // This will validate the signature against the certificate in | |
// // the local store. | |
// if(CryptVerifyMessageSignature( | |
// &VerifyParams, | |
// 0, | |
// pSignedMessageBlob->pbData, | |
// pSignedMessageBlob->cbData, | |
// pbDecodedMessageBlob, | |
// &cbDecodedMessageBlob, | |
// NULL)) | |
// { | |
// _tprintf(TEXT("The verified message is \"%s\".\n"), | |
// pbDecodedMessageBlob); | |
// | |
// fReturn = true; | |
// } | |
// else | |
// { | |
// _tprintf(TEXT("Verification message failed. \n")); | |
// } | |
// | |
//exit_VerifySignedMessage: | |
// // If something failed and the decoded message buffer was | |
// // allocated, free it. | |
// if(!fReturn) | |
// { | |
// if(pbDecodedMessageBlob) | |
// { | |
// free(pbDecodedMessageBlob); | |
// pbDecodedMessageBlob = NULL; | |
// } | |
// } | |
// | |
// // If the decoded message buffer is still around, it means the | |
// // function was successful. Copy the pointer and size into the | |
// // output parameter. | |
// if(pbDecodedMessageBlob) | |
// { | |
// pDecodedMessageBlob->cbData = cbDecodedMessageBlob; | |
// pDecodedMessageBlob->pbData = pbDecodedMessageBlob; | |
// } | |
// | |
// return fReturn; | |
//} | |
NSString* SignMessage(CRYPT_DATA_BLOB *pSignedMessageBlob) | |
{ | |
// если файл myCert.cer | |
// NSString* certPath = [[NSBundle mainBundle] pathForResource:@"Ivan2asdov2001" ofType:@"pfx"]; | |
// NSData* certData = [[NSFileManager defaultManager] contentsAtPath:certPath]; | |
// NSString *psw = @"1111"; | |
// const char* szPassword = [psw UTF8String]; | |
// | |
// // данные | |
// const void* pData = certData.bytes; | |
// int szData = certData.length; | |
FILE *hInputFile; | |
BYTE *pbBlob; | |
//bool pPFX = false; | |
bool fReturn = false; | |
BYTE* pbMessage; | |
DWORD cbMessage; | |
HCERTSTORE hCertStore = NULL; | |
//CRYPT_DATA_BLOB cert_struct = { szData, pData }; | |
//HCERTSTORE hCertStore = PFXImportCertStore(&cert_struct, NULL, CRYPT_EXPORTABLE); | |
LPCWSTR szPassword = L"1111"; | |
HCRYPTPROV hProv; | |
HCRYPTKEY hKey = 0; | |
NSString* certPath = [[NSBundle mainBundle] pathForResource:@"Gorlov2001" ofType:@"pfx"]; | |
NSData* certData = [[NSFileManager defaultManager] contentsAtPath:certPath]; | |
NSString* signPath = [[NSBundle mainBundle] pathForResource:@"test2File_hash" ofType:@"dat"]; | |
NSData* signData = [[NSFileManager defaultManager] contentsAtPath:signPath]; | |
NSString* base64String = [[NSString alloc] initWithFormat:@"g1id79JP8mK3I9CAE/MkbASbdzH1+netJHwv5VxTw/Y="]; | |
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:base64String options:0]; | |
// данныe | |
const BYTE * sData = decodedData.bytes; | |
DWORD sszData = decodedData.length; | |
// | |
// const char* sData = signData.bytes; | |
// const float sszData = signData.length; | |
// | |
const char* pData = certData.bytes; | |
const float szData = certData.length; | |
BOOL bSilent = FALSE; | |
CRYPT_DATA_BLOB cert_struct = {szData, pData}; | |
CRYPT_DATA_BLOB pDecodedMessageBlob = {}; | |
//NSLog((__bridge id)(PFXImportCertStore(&cert_struct, szPassword, CRYPT_EXPORTABLE))); | |
PCCERT_CONTEXT pSignerCert; | |
CRYPT_SIGN_MESSAGE_PARA SigParams; | |
DWORD cbSignedMessageBlob; | |
BYTE *pbSignedMessageBlob = NULL; | |
DWORD pcchString; | |
LPSTR pszString = NULL; | |
// Initialize the output pointer. | |
pSignedMessageBlob->cbData = 0; | |
pSignedMessageBlob->pbData = NULL; | |
// The message to be signed. | |
// Usually, the message exists somewhere and a pointer is | |
// passed to the application. | |
// NSString *base64String = [@"bpdy5kCskODVyxospbTVsEUWlpzDxKhH4rCjqnWHSKY=" dataUsingEncoding:NSUTF8StringEncoding]; | |
// NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:base64String options:0]; | |
// NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding]; | |
// NSLog(@"Decode String Value: %@", decodedString); | |
//NSData *data1 =[@"My String" dataUsingEncoding:NSUTF8StringEncoding]; | |
//NSString *base64String = ; | |
// | |
// | |
// NSData *data = [NSData dataFromBase64String:base64String]; | |
// NSString *decodedString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; | |
// | |
// | |
//// NSData *nsdataDecoded = [base64Data initWithBase64EncodedData:base64Data options:0]; | |
//// NSString *result = [[NSString alloc] initWithData:nsdataDecoded encoding:NSUTF8StringEncoding]; | |
//// | |
// NSLog(@"decodedString%@", decodedString); | |
pbMessage = sData; | |
// Calculate the size of message. To include the | |
// terminating null character, the length is one more byte | |
// than the length returned by the strlen function. | |
cbMessage = (strlen((TCHAR*) sData) + 1) * sizeof(TCHAR); | |
// Create the MessageArray and the MessageSizeArray. | |
const BYTE* MessageArray[] = {sData}; | |
DWORD MessageSizeArray[1]; | |
MessageSizeArray[0] = cbMessage; | |
// Begin processing. | |
_tprintf(TEXT("The message to be signed is \"%s\".\n"), | |
pbMessage); | |
//Open the certificate store. | |
if ( !( hCertStore = hCertStore = PFXImportCertStore(&cert_struct, szPassword, CRYPT_EXPORTABLE))) | |
{ | |
MyHandleError(TEXT("The MY store could not be opened.")); | |
//goto exit_SignMessage; | |
}else{ | |
_tprintf(TEXT("Cert store is HERE")); | |
} | |
// LPCTSTR pszContainerName = TEXT("My Sample Key Container"); | |
// Get a pointer to the signer's certificate. | |
// This certificate must have access to the signer's private key. | |
if(pSignerCert = CertFindCertificateInStore( | |
hCertStore, | |
MY_ENCODING_TYPE, | |
0, | |
CERT_FIND_ANY, | |
NULL, | |
NULL)) | |
{ | |
_tprintf(TEXT("The signer's certificate was found.\n")); | |
} | |
else | |
{ | |
MyHandleError( TEXT("Signer certificate not found.")); | |
//goto exit_SignMessage; | |
} | |
// Initialize the signature structure. | |
SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA); | |
SigParams.dwMsgEncodingType = MY_ENCODING_TYPE; | |
SigParams.pSigningCert = pSignerCert; | |
SigParams.HashAlgorithm.pszObjId = szOID_CP_GOST_R3411; | |
SigParams.HashAlgorithm.Parameters.cbData = NULL; | |
SigParams.cMsgCert = 1; | |
SigParams.rgpMsgCert = &pSignerCert; | |
SigParams.cAuthAttr = 0; | |
SigParams.dwInnerContentType = 0; | |
SigParams.cMsgCrl = 0; | |
SigParams.cUnauthAttr = 0; | |
SigParams.dwFlags = 0; | |
SigParams.pvHashAuxInfo = NULL; | |
SigParams.rgAuthAttr = NULL; | |
// First, get the size of the signed BLOB. | |
if(CryptSignMessage( | |
&SigParams, | |
TRUE, | |
1, | |
&sData, | |
&sszData, | |
NULL, | |
&cbSignedMessageBlob)) | |
{ | |
_tprintf(TEXT("%d bytes needed for the encoded BLOB.\n"), | |
sszData); | |
} | |
else | |
{ | |
MyHandleError(TEXT("Getting signed BLOB size failed")); | |
//goto exit_SignMessage; | |
} | |
// Allocate memory for the signed BLOB. | |
if(!(pbSignedMessageBlob = | |
(BYTE*)malloc(cbSignedMessageBlob))) | |
{ | |
MyHandleError( | |
TEXT("Memory allocation error while signing.")); | |
//goto exit_SignMessage; | |
} | |
// Get the signed message BLOB. | |
if(CryptSignMessage( | |
&SigParams, | |
TRUE, | |
1, | |
&sData, | |
&sszData, | |
pbSignedMessageBlob, | |
&cbSignedMessageBlob)) | |
{ | |
_tprintf(TEXT("The message was signed successfully. \n")); | |
//_tprintf(TEXT("%d "), pSignerCert->pCertInfo->SignatureAlgorithm.pszObjId); | |
// pbSignedMessageBlob now contains the signed BLOB. | |
//_tprintf("BLOB HERE: %d", sData); | |
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); | |
NSString *documentsDirectory = [paths objectAtIndex:0]; | |
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"Sign7.dat"]; | |
NSError * error = nil; | |
NSData * outData = [NSData dataWithBytes:pbSignedMessageBlob length:cbSignedMessageBlob]; | |
[outData writeToFile:dataPath options:NSDataWritingAtomic error:&error]; | |
NSLog (@"error: %@", error); | |
// | |
// // Allocate memory for the signed BLOB. | |
// if(!(pszString = | |
// (BYTE*)malloc(cbSignedMessageBlob))) | |
// { | |
// MyHandleError( | |
// TEXT("Memory allocation error while signing.")); | |
// goto exit_SignMessage; | |
// } | |
// LPCSTR pszSource = "Man is distinguished, not only by his reason, but ..."; | |
// DWORD nDestinationSize; | |
// if (CryptBinaryToString(reinterpret_cast<const BYTE*> (pszSource), strlen(pszSource), CRYPT_STRING_BASE64, nullptr, &nDestinationSize)) | |
// { | |
// LPTSTR pszDestination = static_cast<LPTSTR> (HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, nDestinationSize * sizeof(TCHAR))); | |
// if (pszDestination) | |
// { | |
// if (CryptBinaryToString(reinterpret_cast<const BYTE*> (pszSource), strlen(pszSource), CRYPT_STRING_BASE64, pszDestination, &nDestinationSize)) | |
// { | |
// // Succeeded: 'pszDestination' is 'pszSource' encoded to base64. | |
// } | |
// HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pszDestination); | |
// } | |
// } | |
// | |
// | |
// | |
// | |
// | |
// if(CryptBinaryToStringA(&pbSignedMessageBlob, 1, CRYPT_STRING_BASE64, NULL, &pcchString)) | |
// { | |
// _tprintf(TEXT("%d bytes needed for the encoded base64.\n"), | |
// pcchString); | |
// }else{ | |
// _tprintf(TEXT("%d bytes needed for the encoded base64.\n"), | |
// pcchString); | |
// } | |
// | |
// | |
// if(CryptBinaryToStringA(&pbSignedMessageBlob, 1, CRYPT_STRING_BASE64, pszString, &pcchString)){ | |
// _tprintf(TEXT("The message was converted to base64 \n")); | |
// _tprintf("Converted value: %s", pszString); | |
// | |
// }else{ | |
// _tprintf(TEXT("Something went wrong")); | |
// | |
// } | |
// if (error) { | |
// NSLog(@"%@", [error localizedDescription]); | |
// } else { | |
// //NSLog(@"%@", myString); | |
// } | |
// //FILE *dic = fopen([filePath cStringUsingEncoding: NSUTF8StringEncoding], "r"); | |
// | |
// if( !(hInputFile= fopen([filePath cStringUsingEncoding: NSUTF8StringEncoding], "r"))) | |
// { | |
// MyHandleError(TEXT("Input file was not opened.\n")); | |
// }else{ | |
// | |
//// NSData * inData = [NSData dataWithContentsOfFile:dataPath]; | |
//// assert (inData); | |
//// | |
// //[outData writeToFile:dataPath atomically:YES]; | |
// } | |
// fread( | |
// pbSignedMessageBlob, | |
// sizeof(DWORD), | |
// 1, | |
// hInputFile); | |
// | |
// if(ferror(hInputFile)) | |
// { | |
// MyHandleError(TEXT("The size of the BLOB was not read.\n")); | |
// } | |
// if(!(pbBlob = (BYTE *) malloc(*pbSignedMessageBlob))) | |
// { | |
// MyHandleError(TEXT("Memory allocation failed.")); | |
// } | |
fReturn = true; | |
} | |
else | |
{ | |
MyHandleError(TEXT("Error getting signed BLOB")); | |
//goto exit_SignMessage; | |
} | |
// exit_SignMessage: | |
// | |
// // Clean up and free memory as needed. | |
// if(pSignerCert) | |
// { | |
// CertFreeCertificateContext(pSignerCert); | |
// } | |
// | |
// if(hCertStore) | |
// { | |
// CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG); | |
// hCertStore = NULL; | |
// } | |
// | |
// // Only free the signed message if a failure occurred. | |
// if(!fReturn) | |
// { | |
// if(pbSignedMessageBlob) | |
// { | |
// free(pbSignedMessageBlob); | |
// pbSignedMessageBlob = NULL; | |
// } | |
// } | |
if(pbSignedMessageBlob) | |
{ | |
pSignedMessageBlob->cbData = cbSignedMessageBlob; | |
pSignedMessageBlob->pbData = pbSignedMessageBlob; | |
} | |
//VerifySignedMessage(pSignedMessageBlob, &pDecodedMessageBlob); | |
// | |
NSData * outData = [NSData dataWithBytes:pbSignedMessageBlob length:cbSignedMessageBlob]; | |
// | |
NSString *str = [outData base64EncodedStringWithOptions:0]; //return encoded and signed | |
return str; | |
} | |
// To export module named CSPManager | |
//RCT_EXPORT_MODULE(); | |
NSString* importCert(){ | |
DisableIntegrityCheck(); | |
HCRYPTPROV hProv; | |
HCRYPTKEY hKey = 0; | |
NSString* certPath = [[NSBundle mainBundle] pathForResource:@"Gorlov2001" ofType:@"pfx"]; | |
NSData* certData = [[NSFileManager defaultManager] contentsAtPath:certPath]; | |
LPCWSTR szPassword = L"1111"; | |
// данные | |
const char* pData = certData.bytes; | |
const float szData = certData.length; | |
BOOL bSilent = FALSE; | |
CRYPT_DATA_BLOB cert_struct = {szData, pData}; | |
// LPCTSTR pszContainerName = TEXT("My Sample Key Container"); | |
// HCERTSTORE hCertStore = PFXImportCertStore(&cert_struct, szPassword, CRYPT_EXPORTABLE); | |
// FILE *f = fopen("Gorlov2001.pfx" , "r"); | |
// fseek (f , 0 , SEEK_END); | |
// cert_struct.cbData = (DWORD)ftell (f); | |
// fseek(f, 0, SEEK_SET); | |
// cert_struct.pbData = (BYTE *)malloc(cert_struct.cbData); | |
// fread(cert_struct.pbData, 1, cert_struct.cbData, f); | |
// fclose(f); | |
// if(CryptAcquireContext( | |
// &hProv, | |
// #ifdef _WIN32 | |
// "\\\\.\\REGISTRY\\KC1_test", | |
// #else | |
// "\\\\.\\HDIMAGE\\KC1_test", | |
// #endif | |
// NULL, | |
// PROV_GOST_2001_DH, | |
// CRYPT_NEWKEYSET | (bSilent ? CRYPT_SILENT : 0) | |
//)){ | |
// printf("CSP context acquired.\n"); | |
// printf("PATH: ", certPath); | |
// HCERTSTORE hCertStore = PFXImportCertStore(&cert_struct, szPassword, CRYPT_EXPORTABLE); | |
// printf("CertStore imported!.\n"); | |
// | |
// }else{ | |
// printf("CSP context failed HEREEE.\n"); | |
// } | |
//// | |
//HCERTSTORE hCertStore = PFXImportCertStore(&cert_struct, szPassword, CRYPT_EXPORTABLE); | |
// NSLog(@"LENGTH: %f", szData); | |
//_tprintf("RETURNED OF ALL: %s", SignMessage(&cert_struct)); | |
NSString *message = SignMessage(&cert_struct); | |
NSLog(@"message HERE: %@", message); | |
return message; | |
//return hCertStore; | |
//NSLog((__bridge id)(PFXImportCertStore(&cert_struct, szPassword, CRYPT_EXPORTABLE))); | |
} | |
//NSLog(@"IMPORTING CERT: ", importCert()); | |
RCT_EXPORT_METHOD(signHash:(RCTResponseSenderBlock)callback) | |
{ | |
NSString *testString = importCert(); | |
NSLog(@"Importing CERT:%@", testString); | |
callback(@[testString]); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment