Skip to content

Instantly share code, notes, and snippets.

@nosalvage
Created November 20, 2018 13:58
Show Gist options
  • Save nosalvage/621b8ba7cdf088a7de8021f6a713863c to your computer and use it in GitHub Desktop.
Save nosalvage/621b8ba7cdf088a7de8021f6a713863c to your computer and use it in GitHub Desktop.
//
// 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