Using CryptoAPI to generate ascii cipher text - winapi

Specifically what i'm trying to do is Generate a PassStub field for a Remote Assistance ticket. The problem is that my results look like binary data but somehow Microsoft generates printable characters.
In [MS-RAI]: Remote Assistance Initiation Protocol Specification <16> Section 6: Microsoft says that the "PassStub" field "is encrypted using PROV_RSA_FULL predefined Cryptographic provider with MD5 hashing and CALG_RC4, the RC4 stream encryption algorithm."
There is a data flow diagram here:
http://msdn.microsoft.com/en-us/library/cc240189(PROT.10).aspx#id16
The diagram shows the hashed password being encrypted with a "RA SessionID" which looks like this: u0RIQibSMntm0wAHQZ2mhatI63sjMjX15kh/vnciytOix8z6w+36B01OiJoB5uYe
When I call CryptEncrypt the result is binary data about the length of the SessionID. Microsoft somehow gets something that looks like this: "Po^1BiNrHBvHGP"
Here is the code i'm trying to use to do this:
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHash;
BOOL bret=0;
passwordlen = SysStringByteLen(L"password");
char RASessionID[] = "u0RIQibSMntm0wAHQZ2mhatI63sjMjX15kh/vnciytOix8z6w+36B01OiJoB5uYe";
//----------------------------------------------------------------
// Acquire a cryptographic provider context handle.
if(!CryptAcquireContext(&hCryptProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0))
{
return FALSE;
}
//----------------------------------------------------------------
// Create an empty hash object.
if(!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
{
return FALSE;
}
if(!CryptHashData(hHash, (BYTE *)bpassword, passwordlen, 0))
{
return FALSE;
}
//----------------------------------------------------------------
// Create a session key based on the hash of the password.
if(!CryptDeriveKey(hCryptProv, CALG_RC4, hHash, CRYPT_EXPORTABLE, &hKey))
{
return FALSE;
}
DWORD rasessionidlen = strlen(rasessionid);
char* proxystub = (char*)malloc(rasessionidlen*2);
strcpy(proxystub, rasessionid);
bret = CryptEncrypt(hKey, NULL, TRUE, 0, (BYTE*)proxystub, &rasessionidlen, rasessionidlen*2);
return bret;

The "RA SessionID" looks like it is base64-encoded. My guess would be that the pass-stub is base64-encoded too - except that your example: "Po^1BiNrHBvHGP" is too short and contains a ^. Is that a real example?
You might also need to base64-decode the RA Session ID before feeding it to CryptEncrypt.

Related

Access denied when using WdfRegistryOpenKey function to create registry keys in umdf2

In my WDF driver, I want to save some custom data used for specific device to the registry. But I cannot use the WdfRegistryCreateKey() function provided by umdf2 to create a new key under "hardware_key\Device Parameters" on windows10 1909 platform. The error code is "Access Denied". And I have opened the parent key correctly in READ_KEY mask(if not READ_KEY mask, WdfDeviceOpenRegistryKey() will return STATUS_INVALID_PARAMETER indicate insufficient access rights). How to solve this problem?
Thanks in advance.
// create subkey function definition
NTSTATUS registry_create_key(WDFKEY parent_key, PUNICODE_STRING key_str,
WDFKEY* key)
{
NTSTATUS status;
WDFKEY new_key;
status = WdfRegistryCreateKey(parent_key, key_str, KEY_CREATE_SUB_KEY,
REG_OPTION_NON_VOLATILE, NULL, WDF_NO_OBJECT_ATTRIBUTES,
&new_key);
if (!NT_SUCCESS(status)) {
return status;
}
if (key)
*key = new_key;
else
WdfRegistryClose(new_key);
return status;
}
// open parent key, I have removed the return value judgment for brevity
status = WdfDeviceOpenRegistryKey(
DeviceContext->Device,
PLUGPLAY_REGKEY_DEVICE,
KEY_READ,
WDF_NO_OBJECT_ATTRIBUTES,
&hkey);
// The key name I want to create
UNICODE_STRING myKeyStr;
RtlInitUnicodeString(
&myKeyStr,
L"myKeyStr"
);
// Call the subkey create function
status = registry_create_key(hkey, &myKeyStr, &subkey);
WdfRegistryClose(subkey);
You're opening the parent key for KEY_READ access then trying to create a subkey under it. You need to open the parent key with KEY_CREATE_SUB_KEY access.

Outlook MAPI in C++ application: Get SMTP address (PR_SMTP_ADDRESS) after a IMAPITABLE restrict

I have a PR_ANR_W restriction in my MAPI application, to find users that match a text pattern:
enum
{
abPR_DISPLAY_NAME,
abrPR_EMAIL_ADDRESS,
abPropTagToCompare,
abNUM_COLS
};
const SizedSPropTagArray(abNUM_COLS, abCols) =
{
abNUM_COLS,
PR_DISPLAY_NAME_W,
PR_EMAIL_ADDRESS_W,
PropTagToCompare
};
LPSRestriction lpSRes = nullptr;
CreateANRRestriction(PR_ANR_W, szName, nullptr, &lpSRes); // szName = "diego"
pIMAPITABLE->SetColumns(LPSPropTagArray(&abCols), TBL_BATCH);
pIMAPITABLE->Restrict(lpSRes, NULL);
LPSRowSet pRows = nullptr;
pIMAPITABLE->QueryRows(1, NULL, &pRows);
pRows->aRow->lpProps[abPR_DISPLAY_NAME].Value.lpszW // --> Diego Doñate
pRows->aRow->lpProps[abrPR_EMAIL_ADDRESS].Value.lpszW // --> /o=Company/ou=First Administrative Group/cn=Recipients/cn=diego.dnate#company.com
PR_DISPLAY_NAME_W & PR_EMAIL_ADDRESS_W are in "MAPITags.h"
but there I can not find PR_SMTP_ADDRESS, to get in my case: diego.donate#company.com (not the / cn value from previous string))
How can I get the SMTP address of theses contacts?
Thanks in advance,
Diego
I found it, i had to use the Hex value for PR_SMTP_ADDRESS in SizedSPropTagArray:
PROP_TAG(PT_UNICODE, 0x39FE)

Viewing Ciphertext of Encrypted File on NTFS (EFS)

So I'm doing some testing with data encryption per a course I'm taking in school (for this assignment we're meant to use only a Windows environment), and I'm able to use Windows built-in "cipher.exe" tool just fine for what we need to do.
I made a small .txt file (my plain text), and I encrypted it using "cipher /e PlainText.txt" which has no error. However, I want to be able to view the ciphertext as well. How would one go about doing this? I tried logging in as a user that didn't have the proper access to the file and instead of seeing ciphertext it just comes up blank saying "Access Denied".
Thank you for any ideas.
The way you open an encrypted file in order to read its raw encrypted contents (e.g. for a backup/restore application) is to use the:
OpenEncryptedFileRaw,
ReadEncryptedFileRaw,
WriteEncryptedFileRaw, and
CloseEncryptedFileRaw
api functions.
Writing the code on the fly, in a hypothetical hybrid language:
void ExportEncryptedFileToStream(String filename, Stream targetStream)
{
Pointer context;
res = OpenEncryptedFileRaw("C:\Users\Ian\wallet.dat", 0, ref context);
if (res <> ERROR_SUCCESS)
RaiseWin32Error(res);
try
{
res = ReadEncryptedFileRaw(exportCallback, null, context);
if (res != ERROR_SUCCESS)
RaiseWin32Error(res);
}
finally
{
CloseEncryptedFileRaw(context)
}
}
function ExportCallback(pbData: PBYTE, pvCallbackContext: PVOID, ulLength: ULONG): DWORD
{
Stream targetStream = Stream(pvCallbackContext);
try
{
targetStream.Write(pbData, ulLength);
}
catch (Exception e)
{
return ERROR_WRITE_FAULT;
}
return ERROR_SUCCESS;
}
Note: Any code released into public domain. No attribution required.

Is there a standard to store username and password in WP7 applications?

I would like to ask if there is a standard to store username and password in a Windows Phone application.
I am working on a project that validates the user on every request that is called. So, I want to store the username and password. Maybe even give them the possibility to "remember me", so if there isn't a standard for doing that, I will have to write it myself, but I'm guessing that Microsoft has a build-in one.
Use ProtectedData.
I found this example on Kevin D. Wolf's efficientcoder.net :
public static String Password {
get {
if (IsolatedStorageSettings.ApplicationSettings.Contains(STR_PASSWORÐ)) {
var bytes = IsolatedstorageSettings.Applicationsettings[STR_PASSwORÐ] as byte[];
var unEncrypteBytes = ProtectedData.Unprotect(bytes, null);
return Encoding.UTF8.GetString(unEncrypteBytes, 0, unEncrypteBytes.Length);
} else {
return string.Empty;
}
}
set {
var encryptedBytes = ProtectedData.Protect(Encoding.UTF8.GetBytes(value), null);
IsolatedStorageSettings.ApplicationSettings[STR_PASSWORÐ] = encryptedBytes;
}
}
(Apologies for the cut and paste I had to use a text from image scan)
You should encrypt you passwords and other sensitive data using the ProtectedData class routines, and manually store them in Isolated Storage for your application.
To encrypt
To decrypt
Also, make sure you add a reference to mscorelib extended to your project. I had to learn this the hard way.
A good article on the topic is:
http://debugmode.net/2011/10/16/protecting-password-or-any-data-in-windows-phone-7-using-data-protection-api/

Importing a Private Key to Keychain returns EINVAL error

I am trying to import RSA private keys into the keychain using my application. The first time I import a key using SecKeychainImport() the operation is successful, a subsequent import gives me an EINVAL (100022) error.
This does not happen if I quit and relaunch the app between two imports. I am including the source code below.
CFArrayRef array = (CFArrayRef)[NSMutableArray array];
SecExternalFormat format = kSecFormatUnknown;
//We are always storing a private key…
SecExternalItemType type = kSecItemTypePrivateKey;
SecKeyImportExportParameters params;
SecKeychainRef keychain;
SecKeychainCopyDefault(&keychain);
memset(&params, 0, sizeof(params));
params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
params.flags = kSecKeyNoAccessControl;
params.keyUsage = CSSM_KEYUSE_ANY;
params.keyAttributes = CSSM_KEYATTR_EXTRACTABLE;
err = SecKeychainItemImport((CFDataRef)data,
(CFStringRef)#"pem",
&format,
&type,
0,
NULL,
keychain,
&array);
if(err == noErr)
{
//Change the kSecKeyPrintName attribute of the keychain item.
}
else
{
//Handle the error by displaying appropriate alert.
}
Am I missing anything obvious?
Try setting the CSSM_KEYATTR_PERMANENT bit in params.keyAttribute. On Lion, I can import multiple PEM-armoured RSA private keys (generated with openssl genrsa) into a keychain if I explicitly set this attribute. If I don't, I get errSecItemNotFound (-25300) when importing the very first key.
(Don't forget to remove kSecKeyNoAccessControl before deploying this code in production. Also, if you generate the key yourself, consider using SecKeyGenerate/SecKeyGenerateSymmetric instead.)

Resources