Ejemplo n.º 1
0
int WXBizMsgCrypt::DecryptMsg(const std::string &sMsgSignature,
                const std::string &sTimeStamp,
                const std::string &sNonce,
                const std::string &sPostData,
                std::string &sMsg)
{
    //1.validate xml format
    std::string sEncryptMsg;
    if(0 != GetXmlField(sPostData,"Encrypt",sEncryptMsg))
    {
        return WXBizMsgCrypt_ParseXml_Error;
    }

    //2.validate signature
    if(0 != ValidateSignature(sMsgSignature,sTimeStamp,sNonce,sEncryptMsg) ) 
    {
        return WXBizMsgCrypt_ValidateSignature_Error;
    }

    //3.decode base64
    std::string sAesData;
    if(0 != DecodeBase64(sEncryptMsg,sAesData))
    {
        return WXBizMsgCrypt_DecodeBase64_Error;
    }
    
    //4.decode aes
    std::string sAesKey;
    std::string sNoEncryptData;
    if(0 != GenAesKeyFromEncodingKey(m_sEncodingAESKey,sAesKey)) 
    {
        return WXBizMsgCrypt_IllegalAesKey;
    }
    if(0 != AES_CBCDecrypt(sAesData, sAesKey, &sNoEncryptData))
    {
        return WXBizMsgCrypt_DecryptAES_Error;
    }

    // 5. remove kRandEncryptStrLen str 
    if(sNoEncryptData.size() <= (kRandEncryptStrLen + kMsgLen))
    {
        return WXBizMsgCrypt_IllegalBuffer;
    }  
    uint32_t iNetLen = *((const uint32_t *)(sNoEncryptData.c_str() + kRandEncryptStrLen));
    uint32_t iMsgLen = ntohl(iNetLen);
    if(sNoEncryptData.size() <= (kRandEncryptStrLen + kMsgLen + iMsgLen))
    {
        return WXBizMsgCrypt_IllegalBuffer;
    }
    sMsg = sNoEncryptData.substr(kRandEncryptStrLen+kMsgLen,iMsgLen );

    //6. validate appid
    std::string sAppid = sNoEncryptData.substr(kRandEncryptStrLen+kMsgLen+iMsgLen);
    if(sAppid != m_sAppid)
    {
        return WXBizMsgCrypt_ValidateAppid_Error;
    }
   
    return WXBizMsgCrypt_OK;
}
// Decode a x509v3 Certificate
void CertDecoder::Decode(SignerList* signers, CertType ct)
{
    if (source_.GetError().What()) return;
    DecodeToKey();
    if (source_.GetError().What()) return;

    if (source_.get_index() != sigIndex_)
        source_.set_index(sigIndex_);

    word32 confirmOID = GetAlgoId();
    GetSignature();
    if (source_.GetError().What()) return;

    if ( confirmOID != signatureOID_ ) {
        source_.SetError(SIG_OID_E);
        return;
    }

    if (ct != CA && verify_ && !ValidateSignature(signers))
            source_.SetError(SIG_OTHER_E);
}
int ValidateAsset(const char* asset_dir_path, unsigned long current_version)
{
	const char* files[] = 
	{
		"certs.plist",
		"distrusted.plist",
		"EVRoots.plist",
		"Manifest.plist",
		"revoked.plist",
		"roots.plist"
	};
	int num_files = (sizeof(files) / sizeof(const char*));
	int iCnt = 0;
	const char* file_name = NULL;
    char wd_buf[1024];
    
	const char* current_working_directory_path = getcwd(wd_buf, 1024);
	CFDataRef file_data = NULL;
	CFDataRef hash_data = NULL;
	CFDataRef encoded_hash_data = NULL;
	CFStringRef manifest_hash_data_str = NULL;
	CFDataRef signature_data = NULL;
	CFStringRef key_name = NULL;
	CFDictionaryRef manifest_dict = NULL;
    CFNumberRef manifest_version = NULL;
    CFStringRef encoded_hash_str = NULL;
	CFDataRef manifest_data = NULL;
    unsigned long manifest_verson_number;
	int iResult = -1;
	
	// parameter check
	if (NULL == asset_dir_path)
	{
		return iResult;
	}
	
	if (ValidateFilesInDirectory(asset_dir_path, num_files, files))
	{
		return iResult;
	}	
	
	if (chdir(asset_dir_path))
	{
		return iResult;
	}
	
	if (ReadFileIntoCFDataRef("Manifest.plist", &file_data))
	{
		(void)chdir(current_working_directory_path);
		return iResult;
	}
	
	if (CreatePropertyListFromData(file_data,  CFDictionaryGetTypeID(), (CFTypeRef *)&manifest_dict))
	{
		CFRelease(file_data);
		(void)chdir(current_working_directory_path);
		return iResult;
	}
	CFRelease(file_data);
		
	// Validate the hash for the files in the manifest
	for (iCnt = 0; iCnt < num_files; iCnt++)
	{
		file_name = files[iCnt];
		// bypass the manifest file for now
		if (!strcmp("Manifest.plist", file_name))
		{
			continue;
		}
		
		if (ReadFileIntoCFDataRef(file_name, &file_data))
		{
			CFRelease(manifest_dict);
			(void)chdir(current_working_directory_path);
			return iResult;
		}
		
		if (CreateHashForData(file_data, 0, &hash_data))
		{
			CFRelease(file_data);
			CFRelease(manifest_dict);
			(void)chdir(current_working_directory_path);
			return iResult;
		}
		CFRelease(file_data);
        
		
		if (Base64Data(hash_data, 1, &encoded_hash_data))
		{
			CFRelease(hash_data);
			CFRelease(manifest_dict);
			(void)chdir(current_working_directory_path);
			return iResult;
		}
		CFRelease(hash_data);
        
        encoded_hash_str = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, encoded_hash_data, kCFStringEncodingUTF8);
        if (NULL == encoded_hash_str)
        {
            CFRelease(encoded_hash_data);
            CFRelease(manifest_dict);
			(void)chdir(current_working_directory_path);
			return iResult;
        }
        CFRelease(encoded_hash_data);
		
		key_name = CFStringCreateWithCString(kCFAllocatorDefault, file_name, kCFStringEncodingUTF8);
		if (NULL == key_name)
		{
			CFRelease(encoded_hash_str);
			CFRelease(manifest_dict);
			(void)chdir(current_working_directory_path);
			return iResult;
		}
		
		manifest_hash_data_str = (CFStringRef)CFDictionaryGetValue(manifest_dict, key_name);
		if (NULL == manifest_hash_data_str)
		{
			CFRelease(key_name);
			CFRelease(encoded_hash_str);
			CFRelease(manifest_dict);
			(void)chdir(current_working_directory_path);
			return iResult;
		}
		CFRelease(key_name);
		
		if (!CFEqual(encoded_hash_str, manifest_hash_data_str))
		{
			CFRelease(encoded_hash_str);
			CFRelease(manifest_dict);
			(void)chdir(current_working_directory_path);
			return iResult;
		}
		CFRelease(encoded_hash_str);
	}
	
	// Get the version
    manifest_version = (CFNumberRef)CFDictionaryGetValue(manifest_dict, CFSTR("Version"));
    if (NULL == manifest_version)
    {
        CFRelease(manifest_dict);
		(void)chdir(current_working_directory_path);
		return iResult;
    }
    
    if (!CFNumberGetValue(manifest_version, kCFNumberLongType, &manifest_verson_number))
    {
        CFRelease(manifest_version);
        CFRelease(manifest_dict);
		(void)chdir(current_working_directory_path);
		return iResult;
    }
    CFRelease(manifest_version);
    if (manifest_verson_number < current_version)
    {
        CFRelease(manifest_dict);
		(void)chdir(current_working_directory_path);
		return iResult;
    }
    
    // Deal with the signature
	if (TearOffSignatureAndHashManifest(manifest_dict, &signature_data, &manifest_data))
	{
		CFRelease(manifest_dict);
		(void)chdir(current_working_directory_path);
		return iResult;
	}	
	
	iResult = ValidateSignature(signature_data, manifest_data);
	CFRelease(signature_data);
	CFRelease(manifest_data);
	CFRelease(manifest_dict);
	(void)chdir(current_working_directory_path);
	return iResult;    
}