Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1108 lines
39 KiB

#include "item.h"
#define MAX_LAYERS 30
extern HINSTANCE hInst;
extern const BYTE RgbSHA1AlgId[] =
{0x30, 0x09, 0x30, 0x07, 0x06, 0x05, 0x2B, 0x0E,
0x03, 0x02, 0x1A};
extern const int CbSHA1AlgId = sizeof(RgbSHA1AlgId);
byte RgbEntityId1[] = {0x1, 0x4, 0x7, 0x8, 0x10};
byte RgbEntityId2[] = {0x1, 0x4, 0x7, 0x10, 0x8};
const char SzPolicyRoot[] = "Software\\Microsoft\\Cryptography\\OID\\EncodingType 1\\SMimeSecurityLabel";
//const char SzPolicyRoot[] = "Software\\Microsoft\\Cryptography\\SMIME\\SecurityPolicies";
class CSecurityPolicy {
public:
DWORD dwFlags;
char * szDllName;
char * szPolicyOID;
char * szFuncName;
HMODULE hmod;
PFNGetSMimePolicy pfnFuncName;
ISMimePolicySimpleEdit * ppolicy;
CSecurityPolicy() {
szDllName = szPolicyOID = szFuncName = NULL;
hmod = 0;
pfnFuncName = NULL;
ppolicy = NULL;
dwFlags = 0;
}
~CSecurityPolicy() {
free(szDllName);
free(szPolicyOID);
free(szFuncName);
if (ppolicy != NULL) ppolicy->Release();
FreeLibrary(hmod);
}
};
////////////////////////////////////////////////////////////////////////////
BOOL CALLBACK MLDataCreateDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
DWORD cb;
DWORD cb2;
BOOL f;
SMIME_ML_EXPANSION_HISTORY mlHistory;
LPBYTE pb;
PSMIME_ML_EXPANSION_HISTORY pMLHistory;
static PCCERT_CONTEXT pccert1 = NULL;
static PCCERT_CONTEXT pccert2 = NULL;
static CSignData * psd = NULL;
char rgch[256];
SMIME_MLDATA rgMLData[5];
switch (msg) {
case WM_INITDIALOG:
pccert1 = NULL;
pccert2 = NULL;
psd = (CSignData *) lParam;
#if 0
psd->GetMLHistory(&pb, &cb);
if (cb > 0) {
f = CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_SMIME_MLExpansion_History,
pb, cb, CRYPT_ENCODE_ALLOC_FLAG, NULL,
&pMLHistory, &cb2);
}
#endif // 0
break;
case WM_COMMAND:
switch (wParam) {
case MAKELONG(IDC_MLC_SELECT1, BN_CLICKED):
if (DoCertDialog(hdlg, "Choose ML Data Certificate",
psd->GetMyStore(), &pccert1,
FILTER_RSA_SIGN | FILTER_DSA_SIGN)) {
GetFriendlyNameOfCertA(pccert1, rgch, sizeof(rgch));
SetDlgItemText(hdlg, IDC_MLC_CERT1, rgch);
}
break;
case MAKELONG(IDC_MLC_SELECT2, BN_CLICKED):
if (DoCertDialog(hdlg, "Choose ML Data Certificate",
psd->GetMyStore(), &pccert2,
FILTER_RSA_SIGN | FILTER_DSA_SIGN)) {
GetFriendlyNameOfCertA(pccert2, rgch, sizeof(rgch));
SetDlgItemText(hdlg, IDC_MLC_CERT2, rgch);
}
break;
case MAKELONG(IDC_MLC_ABSENT1, BN_CLICKED):
case MAKELONG(IDC_MLC_NONE1, BN_CLICKED):
EnableWindow(GetDlgItem(hdlg, IDC_MLC_NAMES1), FALSE);
break;
case MAKELONG(IDC_MLC_INSTEAD1, BN_CLICKED):
case MAKELONG(IDC_MLC_ALSO1, BN_CLICKED):
EnableWindow(GetDlgItem(hdlg, IDC_MLC_NAMES1), TRUE);
break;
case MAKELONG(IDC_MLC_ABSENT2, BN_CLICKED):
case MAKELONG(IDC_MLC_NONE2, BN_CLICKED):
EnableWindow(GetDlgItem(hdlg, IDC_MLC_NAMES2), FALSE);
break;
case MAKELONG(IDC_MLC_INSTEAD2, BN_CLICKED):
case MAKELONG(IDC_MLC_ALSO2, BN_CLICKED):
EnableWindow(GetDlgItem(hdlg, IDC_MLC_NAMES2), TRUE);
break;
case IDOK:
memset(&mlHistory, 0, sizeof(mlHistory));
memset(rgMLData, 0, sizeof(rgMLData));
mlHistory.cMLData = 0;
mlHistory.rgMLData = rgMLData;
mlHistory.cMLData = 1;
if (pccert1 == NULL) {
break;
}
if (SendDlgItemMessage(hdlg, IDC_MLC_ID1, BM_GETCHECK, 0, 0)) {
rgMLData[0].dwChoice = SMIME_MLDATA_SUBJECT_KEY_IDENTIFIER;
rgMLData[0].SubjectKeyIdentifier.cbData = sizeof(RgbEntityId1);
rgMLData[0].SubjectKeyIdentifier.pbData = RgbEntityId1;
}
else {
rgMLData[0].dwChoice = SMIME_MLDATA_ISSUER_SERIAL_NUMBER;
rgMLData[0].u.SerialNumber = pccert1->pCertInfo->SerialNumber;
rgMLData[0].u.Issuer = pccert1->pCertInfo->Issuer;
}
GetSystemTimeAsFileTime(&rgMLData[0].ExpansionTime);
if (SendDlgItemMessage(hdlg, IDC_MLC_ABSENT1, BM_GETCHECK, 0, 0)) {
rgMLData[0].dwPolicy = SMIME_MLPOLICY_NO_CHANGE;
}
else if (SendDlgItemMessage(hdlg, IDC_MLC_NONE1, BM_GETCHECK, 0, 0)) {
rgMLData[0].dwPolicy = SMIME_MLPOLICY_NONE;
}
else if (SendDlgItemMessage(hdlg, IDC_MLC_INSTEAD1, BM_GETCHECK, 0, 0)) {
rgMLData[0].dwPolicy = SMIME_MLPOLICY_INSTEAD_OF;
if (!ParseNames(&rgMLData[0].cNames, &rgMLData[0].rgNames,
hdlg, IDC_MLC_NAMES1)) {
return FALSE;
}
}
else {
rgMLData[0].dwPolicy = SMIME_MLPOLICY_IN_ADDITION_TO;
if (!ParseNames(&rgMLData[0].cNames, &rgMLData[0].rgNames,
hdlg, IDC_MLC_NAMES1)) {
return FALSE;
}
}
if (SendDlgItemMessage(hdlg, IDC_MLC_INCLUDE2, BM_GETCHECK, 0, 0)) {
mlHistory.cMLData = 2;
if (pccert2 == NULL) {
break;
}
if (SendDlgItemMessage(hdlg, IDC_MLC_ID2, BM_GETCHECK, 0, 0)) {
rgMLData[1].dwChoice = SMIME_MLDATA_SUBJECT_KEY_IDENTIFIER;
rgMLData[1].SubjectKeyIdentifier.cbData = sizeof(RgbEntityId2);
rgMLData[1].SubjectKeyIdentifier.pbData = RgbEntityId2;
}
else {
rgMLData[1].dwChoice = SMIME_MLDATA_ISSUER_SERIAL_NUMBER;
rgMLData[1].u.SerialNumber = pccert2->pCertInfo->SerialNumber;
rgMLData[1].u.Issuer = pccert2->pCertInfo->Issuer;
}
GetSystemTimeAsFileTime(&rgMLData[1].ExpansionTime);
if (SendDlgItemMessage(hdlg, IDC_MLC_ABSENT2, BM_GETCHECK, 0, 0)) {
rgMLData[1].dwPolicy = SMIME_MLPOLICY_NO_CHANGE;
}
else if (SendDlgItemMessage(hdlg, IDC_MLC_NONE2, BM_GETCHECK, 0, 0)) {
rgMLData[1].dwPolicy = SMIME_MLPOLICY_NONE;
}
else if (SendDlgItemMessage(hdlg, IDC_MLC_INSTEAD2, BM_GETCHECK, 0, 0)) {
rgMLData[1].dwPolicy = SMIME_MLPOLICY_INSTEAD_OF;
if (!ParseNames(&rgMLData[1].cNames, &rgMLData[1].rgNames,
hdlg, IDC_MLC_NAMES2)) {
return FALSE;
}
}
else {
rgMLData[1].dwPolicy = SMIME_MLPOLICY_IN_ADDITION_TO;
if (!ParseNames(&rgMLData[1].cNames, &rgMLData[1].rgNames,
hdlg, IDC_MLC_NAMES2)) {
return FALSE;
}
}
}
f = CryptEncodeObjectEx(X509_ASN_ENCODING, szOID_SMIME_MLExpansion_History,
&mlHistory, CRYPT_ENCODE_ALLOC_FLAG, NULL,
&pb, &cb);
if (!f) return FALSE;
psd->SetMLHistory(pb, cb);
case IDCANCEL:
CertFreeCertificateContext(pccert1);
CertFreeCertificateContext(pccert2);
EndDialog(hdlg, wParam);
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////
void InitPolicies(HWND hdlg, DWORD idc1, DWORD idc2, DWORD idc3, DWORD idc4)
{
DWORD cbData;
DWORD cbMaxData;
DWORD cval;
DWORD dw;
FILETIME ft;
HKEY hkey;
HKEY hkey2;
DWORD i;
DWORD i1;
DWORD iSel;
CSecurityPolicy * p;
char * pbData = NULL;
char rgch[256];
if (RegOpenKey(HKEY_LOCAL_MACHINE, SzPolicyRoot, &hkey)) {
return;
}
for (i=0; TRUE; i++) {
cbData =sizeof(rgch);
dw = RegEnumKeyEx(hkey, i, rgch, &cbData, NULL, NULL, NULL, &ft);
if (dw != ERROR_SUCCESS) {
break;
}
dw = RegOpenKey(hkey, rgch, &hkey2);
dw = RegQueryInfoKey(hkey2, NULL, NULL, NULL, NULL, NULL, NULL, &cval,
NULL, &cbMaxData, NULL, NULL);
pbData = (LPSTR) malloc(cbMaxData);
p = new CSecurityPolicy;
p->szPolicyOID = _strdup(rgch);
cbData = cbMaxData;
dw = RegQueryValueEx(hkey2, "DllPath", NULL, &dw, (LPBYTE) pbData, &cbData);
p->szDllName = _strdup(pbData);
dw = RegQueryValueEx(hkey2, "FuncName", NULL, &dw, (LPBYTE) pbData, &cbData);
if (*pbData != 0) {
p->szFuncName = _strdup(pbData);
}
cbData = cbMaxData;
dw = RegQueryValueEx(hkey2, "CommonName", NULL, &dw, (LPBYTE) pbData, &cbData);
iSel = SendDlgItemMessage(hdlg, idc1, CB_ADDSTRING, 0, (LPARAM) pbData);
Assert(iSel != CB_ERR);
if (iSel == CB_ERR) {
continue;
}
SendDlgItemMessage(hdlg, idc1, CB_SETITEMDATA, iSel, (LPARAM) p);
free(pbData); pbData = NULL;
RegCloseKey(hkey2); hkey2 = NULL;
}
//exit:
if (pbData != NULL) free(pbData);
if (hkey != NULL) RegCloseKey(hkey);
if (hkey2 != NULL) RegCloseKey(hkey2);
}
void PolicyFillClassifications(HWND hwnd, DWORD idc1, DWORD idc2, DWORD idc3,
DWORD dw)
{
DWORD cb;
DWORD cbEncode;
DWORD cbMax;
DWORD cClassifications = 0;
DWORD cval;
DWORD dwValue;
DWORD dwDefaultClassification;
HRESULT hr;
DWORD i;
int iSel;
DWORD iSetSel;
CSecurityPolicy * p;
LPBYTE pbEncode;
DWORD * pdwClassifications = NULL;
LPWSTR * pwszClassifications = NULL;
WCHAR rgwch[256];
iSel = SendDlgItemMessage(hwnd, IDC_SD_POLICY, CB_GETCURSEL, 0, 0);
p = (CSecurityPolicy *) SendDlgItemMessage(hwnd, idc1, CB_GETITEMDATA,
iSel, 0);
if (((int) p) == CB_ERR) {
return;
}
if (p->hmod == NULL) {
p->hmod = LoadLibrary(p->szDllName);
if (p->hmod == NULL) {
return;
}
}
if (p->pfnFuncName == NULL) {
p->pfnFuncName = (PFNGetSMimePolicy) GetProcAddress(p->hmod, p->szFuncName);
if (p->pfnFuncName == NULL) {
return;
}
}
if (p->ppolicy == NULL) {
p->pfnFuncName(0, p->szPolicyOID, 1252, IID_ISMimePolicySimpleEdit,
(LPUNKNOWN *) &p->ppolicy);
}
p->ppolicy->GetPolicyInfo(0, &p->dwFlags);
// get the classification information.
hr = p->ppolicy->GetClassifications(0, &cClassifications, &pwszClassifications,
&pdwClassifications,
&dwDefaultClassification);
if (FAILED(hr)) {
goto Error;
}
SendDlgItemMessage(hwnd, idc2, CB_RESETCONTENT, 0, 0);
for (i=0, iSetSel = 0; i<cClassifications; i++) {
iSel = SendDlgItemMessageW(hwnd, idc2, CB_ADDSTRING, 0, (LPARAM) pwszClassifications[i]);
SendDlgItemMessage(hwnd, idc2, CB_SETITEMDATA, iSel, pdwClassifications[i]);
if (dwDefaultClassification == pdwClassifications[i]) {
iSetSel = i;
}
}
SendDlgItemMessage(hwnd, idc2, CB_SETCURSEL, iSetSel, 0);
EnableWindow(GetDlgItem(hwnd, idc3), !!(p->dwFlags & SMIME_POLICY_EDIT_UI));
Error:
return;
}
BOOL CALLBACK SignInfoDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static CSignInfo * psi = NULL;
switch (msg) {
case UM_SET_DATA:
psi = (CSignInfo *) lParam;
SendDlgItemMessage(hdlg, IDC_SI_BLOB_SIGN, BM_SETCHECK,
((psi != NULL) && (psi->m_fBlob)), 0);
break;
case WM_COMMAND:
switch (wParam) {
case MAKELONG(IDC_SI_BLOB_SIGN, BN_CLICKED):
psi->m_fBlob = SendDlgItemMessage(hdlg, IDC_SI_BLOB_SIGN,
BM_GETCHECK, 0, 0);
return FALSE;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
BOOL CALLBACK SignDataDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
DWORD c;
DWORD cb;
DWORD cbEncode;
DWORD cch;
DWORD dw;
BOOL f;
DWORD i;
CSecurityPolicy * p;
LPBYTE pb;
LPBYTE pbEncode;
SMIME_SECURITY_LABEL * plabel;
static CSignData * psd = NULL;
LPWSTR psz;
CHAR rgch[300];
switch (msg) {
case WM_INITDIALOG:
InitPolicies(hdlg, IDC_SD_POLICY, IDC_SD_CLASSIFICATION,
IDC_SD_PRIVACY_MARK, IDC_SD_ADVANCED);
SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_SETCURSEL, 0, 0);
PolicyFillClassifications(hdlg, IDC_SD_POLICY, IDC_SD_CLASSIFICATION,
IDC_SD_ADVANCED, 0);
break;
case UM_SET_DATA:
// Need to extract and build a security label
if (psd != NULL) {
if (SendDlgItemMessage(hdlg, IDC_SD_LABEL, BM_GETCHECK, 0, 0)) {
DWORD dw;
DWORD iSel;
SMIME_SECURITY_LABEL label = {0};
CSecurityPolicy * p;
WCHAR rgwch[255];
iSel = SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_GETCURSEL, 0, 0);
p = (CSecurityPolicy *) SendDlgItemMessage(hdlg, IDC_SD_POLICY,
CB_GETITEMDATA, iSel, 0);
iSel = SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_GETCURSEL,
0, 0);
dw = SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_GETITEMDATA,
iSel, 0);
rgwch[0] = 0;
GetDlgItemTextW(hdlg, IDC_SD_PRIVACY_MARK, rgwch, sizeof(rgwch)/2);
label.pszObjIdSecurityPolicy = p->szPolicyOID;
if (dw == -1) {
label.fHasClassification = FALSE;
}
else {
label.fHasClassification = TRUE;
label.dwClassification = dw;
}
if (rgwch[0] != 0) {
label.wszPrivacyMark = rgwch;
}
else {
label.wszPrivacyMark = NULL;
}
label.cCategories = 0;
f = CryptEncodeObjectEx(X509_ASN_ENCODING, szOID_SMIME_Security_Label,
&label, CRYPT_ENCODE_ALLOC_FLAG, NULL,
&pbEncode, &cbEncode);
Assert(f);
psd->SetLabel(pbEncode, cbEncode);
LocalFree(pbEncode);
}
}
// Fill in the dialog
psd = (CSignData *) lParam;
if ((psd != NULL) && (psd->m_pccert != NULL)) {
GetFriendlyNameOfCertA(psd->m_pccert, rgch, sizeof(rgch));
SetDlgItemText(hdlg, IDC_SD_CERT_NAME, rgch);
}
else {
SetDlgItemText(hdlg, IDC_SD_CERT_NAME, "");
}
SendDlgItemMessage(hdlg, IDC_SD_RECEIPT, BM_SETCHECK,
((psd != NULL) && (psd->m_fReceipt)), 0);
SendDlgItemMessage(hdlg, IDC_SD_USE_SKI, BM_SETCHECK,
((psd != NULL) && (psd->m_fUseSKI)), 0);
SendDlgItemMessage(hdlg, IDC_SD_MLDATA, BM_SETCHECK,
((psd != NULL) && (psd->m_fMLHistory)), 0);
SendDlgItemMessage(hdlg, IDC_SD_AUTHATTRIB, BM_SETCHECK,
((psd != NULL) && (psd->m_fAuthAttrib)), 0);
SendDlgItemMessage(hdlg, IDC_SD_UNAUTHATTRIB, BM_SETCHECK,
((psd != NULL) && (psd->m_fUnAuthAttrib)), 0);
if (psd != NULL) {
psd->GetLabel(&pbEncode, &cbEncode);
SendDlgItemMessage(hdlg, IDC_SD_LABEL, BM_SETCHECK, (cbEncode > 0), 0);
c = SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_GETCOUNT, 0, 0);
if (cbEncode > 0) {
f = CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_SMIME_Security_Label,
pbEncode, cbEncode, CRYPT_ENCODE_ALLOC_FLAG,
NULL, &plabel, &cb);
Assert(f);
for (i=0; i<c; i++) {
p = (CSecurityPolicy *) SendDlgItemMessage(hdlg, IDC_SD_POLICY,
CB_GETITEMDATA, i, 0);
if (strcmp(p->szPolicyOID, plabel->pszObjIdSecurityPolicy) == 0) {
break;
}
}
Assert(i<c);
if (i<c) {
SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_SETCURSEL, i, 0);
PolicyFillClassifications(hdlg, IDC_SD_POLICY,
IDC_SD_CLASSIFICATION,
IDC_SD_ADVANCED,
plabel->dwClassification);
}
LocalFree(plabel);
}
else {
}
}
break;
case WM_COMMAND:
switch (wParam) {
case IDC_SD_CERT_CHOOSE:
if (DoCertDialog(hdlg, "Choose Signing Certificate", psd->GetMyStore(),
&psd->m_pccert, FILTER_RSA_SIGN | FILTER_DSA_SIGN)) {
GetFriendlyNameOfCertA(psd->m_pccert, rgch, sizeof(rgch));
SetDlgItemText(hdlg, IDC_SD_CERT_NAME, rgch);
}
break;
case MAKELONG(IDC_SD_RECEIPT, BN_CLICKED):
psd->m_fReceipt = SendDlgItemMessage(hdlg, IDC_SD_RECEIPT, BM_GETCHECK,
0, 0);
return FALSE;
case MAKELONG(IDC_SD_USE_SKI, BN_CLICKED):
psd->m_fUseSKI = SendDlgItemMessage(hdlg, IDC_SD_USE_SKI, BM_GETCHECK,
0, 0);
return FALSE;
case IDC_SD_DO_RECEIPT:
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_RECEIPT_CREATE), hdlg,
ReceiptCreateDlgProc, (LPARAM) psd);
break;
case IDC_SD_ADVANCED:
// Query the list to get the policy module descriptor
i = SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_GETCURSEL, 0, 0);
p = (CSecurityPolicy *) SendDlgItemMessage(hdlg, IDC_SD_POLICY,
CB_GETITEMDATA, i, 0);
// Query the classification within the policy module
i = SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_GETCURSEL,
0, 0);
dw = SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_GETITEMDATA,
i, 0);
// Query back the privacy mark within the policy mark.
cch = SendDlgItemMessage(hdlg, IDC_SD_PRIVACY_MARK, WM_GETTEXTLENGTH, 0, 0);
if (cch > 0) {
psz = (LPWSTR) LocalAlloc(0, cch);
*psz = 0;
SendDlgItemMessageW(hdlg, IDC_SD_PRIVACY_MARK, WM_GETTEXT, cch, (LPARAM) psz);
}
else {
psz = NULL;
}
// If we already have a security label on this object, grab it.
psd->GetLabel(&pb, &cb);
if (cb > 0) {
pbEncode = (LPBYTE) LocalAlloc(0, cb);
memcpy(pbEncode, pb, cb);
}
else {
pbEncode = NULL;
}
#if 0
// Now call the advanced UI to see what it wants to do. It will return an
// new receipt and we go from there
if (p->ppolicy->EditUI(hdlg, &dw, &psz, &pbEncode, &cb) == S_OK) {
// Put the label back on our object.
psd->SetLabel(pbEncode, cb);
// Put back the classification
c = SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_GETCOUNT, 0, 0);
for (i=0; i<c; i++) {
if (dw == (DWORD) SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION,
CB_GETITEMDATA, i, 0)) {
SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_SETCURSEL, i, 0);
break;
}
}
// Put back the privacy mark
if (psz != NULL) {
SetDlgItemTextW(hdlg, IDC_SD_PRIVACY_MARK, psz);
LocalFree(psz);
}
else {
SetDlgItemTextW(hdlg, IDC_SD_PRIVACY_MARK, L"");
}
}
#endif // 0
// Free the label as encoded, we have already saved it.
if (pbEncode != NULL) {
LocalFree(pbEncode);
}
break;
case MAKELONG(IDC_SD_MLDATA, BN_CLICKED):
psd->m_fMLHistory = SendDlgItemMessage(hdlg, IDC_SD_MLDATA, BM_GETCHECK,
0, 0);
break;
case IDC_SD_DO_MLDATA:
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_MLDATA_CREATE), hdlg,
MLDataCreateDlgProc, (LPARAM) psd);
break;
case MAKELONG(IDC_SD_AUTHATTRIB, BN_CLICKED):
psd->m_fAuthAttrib = SendDlgItemMessage(hdlg, IDC_SD_AUTHATTRIB, BM_GETCHECK,
0, 0);
break;
case IDC_SD_DO_AUTHATTRIB:
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ATTRIB_CREATE), hdlg,
AuthAttribCreateDlgProc, (LPARAM) psd);
break;
case MAKELONG(IDC_SD_UNAUTHATTRIB, BN_CLICKED):
psd->m_fUnAuthAttrib = SendDlgItemMessage(hdlg, IDC_SD_UNAUTHATTRIB, BM_GETCHECK,
0, 0);
break;
case IDC_SD_DO_UNAUTHATTRIB:
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ATTRIB_CREATE), hdlg,
UnAuthAttribCreateDlgProc, (LPARAM) psd);
break;
default:
return FALSE;
}
break;
case WM_DESTROY:
c = SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_GETCOUNT, 0, 0);
for (i=0; i <c; i++) {
p = (CSecurityPolicy *) SendDlgItemMessage(hdlg, IDC_SD_POLICY,
CB_GETITEMDATA, i, 0);
delete p;
}
break;
default:
return FALSE;
}
return TRUE;
}
BOOL CALLBACK SignDataReadDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
DWORD c;
DWORD cb;
DWORD cbEncode;
BOOL f;
DWORD i;
CSecurityPolicy * p;
LPBYTE pbEncode;
SMIME_SECURITY_LABEL * plabel;
static CSignData * psd = NULL;
CHAR rgch[300];
switch (msg) {
case WM_INITDIALOG:
break;
case UM_SET_DATA:
// Fill in the dialog
psd = (CSignData *) lParam;
if ((psd != NULL) && (psd->m_pccert != NULL)) {
GetFriendlyNameOfCertA(psd->m_pccert, rgch, sizeof(rgch));
SetDlgItemText(hdlg, IDC_SDR_CERT_NAME, rgch);
}
else {
SetDlgItemText(hdlg, IDC_SDR_CERT_NAME, "");
}
SendDlgItemMessage(hdlg, IDC_SDR_RECEIPT, BM_SETCHECK,
((psd != NULL) && (psd->m_fReceipt)), 0);
if (psd != NULL) {
psd->GetLabel(&pbEncode, &cbEncode);
SendDlgItemMessage(hdlg, IDC_SD_LABEL, BM_SETCHECK, (cbEncode > 0), 0);
if (cbEncode > 0) {
f = CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_SMIME_Security_Label,
pbEncode, cbEncode, CRYPT_ENCODE_ALLOC_FLAG,
NULL, &plabel, &cb);
Assert(f);
c = SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_GETCOUNT, 0, 0);
for (i=0; i<c; i++) {
p = (CSecurityPolicy *) SendDlgItemMessage(hdlg, IDC_SD_POLICY,
CB_GETITEMDATA, i, 0);
if (strcmp(p->szPolicyOID, plabel->pszObjIdSecurityPolicy) == 0) {
break;
}
}
if (i<c) {
SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_SETCURSEL, i, 0);
PolicyFillClassifications(hdlg, IDC_SD_POLICY,
IDC_SD_CLASSIFICATION,
IDC_SD_ADVANCED,
plabel->dwClassification);
}
else {
SetDlgItemText(hdlg, IDC_SDR_POLICY, plabel->pszObjIdSecurityPolicy);
SetDlgItemInt(hdlg, IDC_SDR_CLASSIFICATION, plabel->dwClassification, TRUE);
}
LocalFree(plabel);
}
else {
}
}
break;
case WM_COMMAND:
switch (wParam) {
case IDC_SD_CERT_CHOOSE:
if (DoCertDialog(hdlg, "Choose Signing Certificate", psd->GetMyStore(),
&psd->m_pccert, FILTER_RSA_SIGN | FILTER_DSA_SIGN)) {
GetFriendlyNameOfCertA(psd->m_pccert, rgch, sizeof(rgch));
SetDlgItemText(hdlg, IDC_SD_CERT_NAME, rgch);
}
break;
case MAKELONG(IDC_SD_RECEIPT, BN_CLICKED):
psd->m_fReceipt = SendDlgItemMessage(hdlg, IDC_SD_RECEIPT, BM_GETCHECK,
0, 0);
return FALSE;
case IDC_SD_DO_RECEIPT:
// Dialog for button
break;
case IDM_VALIDATE:
if (psd->m_pccert != NULL) {
DWORD dw;
HCERTSTORE hstore = NULL;
HrValidateCert(psd->m_pccert, NULL, NULL, &hstore, &dw);
if (hstore != NULL)
if (!CertCloseStore(hstore, CERT_CLOSE_STORE_CHECK_FLAG)) {
AssertSz(FALSE, "Store did not close");
}
}
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
////////
HRESULT CSignInfo::AddToMessage(DWORD * pulLayers, IMimeMessage * pmm, HWND hwnd)
{
HRESULT hr;
CSignData * psd;
DWORD count = 0;
DWORD dwType = 0;
HCERTSTORE hcertstore;
IMimeBody * pmb = NULL;
IMimeSecurity2 * psmime2 = NULL;
IMimeSecurity2 * pms2 = NULL;
PROPVARIANT rgpvAlgHash[MAX_LAYERS] = {0};
PROPVARIANT rgpvAuthAttr[MAX_LAYERS] = {0};
PCCERT_CONTEXT rgpccert[MAX_LAYERS] = {0};
PROPVARIANT var;
hcertstore = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, NULL,
0, NULL);
if (hcertstore == NULL) {
hr = E_FAIL;
goto exit;
}
// Pull out the body interface to set security properties
hr = pmm->BindToObject(HBODY_ROOT, IID_IMimeBody, (LPVOID *) &pmb);
if (FAILED(hr)) goto exit;
// Find out what security already exists
hr = pmb->GetOption(OID_SECURITY_TYPE, &var);
if (FAILED(hr)) goto exit;
dwType = var.ulVal;
// if any security, then we need to push on a new layer, all previous security
// is now on the "y-security" layer and not on the hbody layer
if (dwType != 0) {
hr = pmm->QueryInterface(IID_IMimeSecurity2, (LPVOID *) &pms2);
if (FAILED(hr)) goto exit;
hr = pms2->Encode(hwnd, SEF_SENDERSCERTPROVIDED |
SEF_ENCRYPTWITHNOSENDERCERT);
if (FAILED(hr)) goto exit;
pms2->Release(); pms2 = NULL;
dwType = 0;
pmb->Release(); pmb = NULL;
// Pull out the body interface to set security properties
hr = pmm->BindToObject(HBODY_ROOT, IID_IMimeBody, (LPVOID *) &pmb);
if (FAILED(hr)) goto exit;
}
//
hr = pmb->QueryInterface(IID_IMimeSecurity2, (LPVOID *) &psmime2);
if (FAILED(hr)) goto exit;
if (psmime2 != NULL) {
var.vt = VT_UI4;
var.ulVal = Count();
hr = pmb->SetOption(OID_SECURITY_SIGNATURE_COUNT, &var);
if (FAILED(hr)) goto exit;
}
for (psd = Head(); psd != NULL; psd = psd->Next()) {
hr = psd->BuildArrays(&count, &dwType, rgpvAlgHash, rgpccert,
rgpvAuthAttr, hcertstore, psmime2);
if (FAILED(hr)) goto exit;
}
if (m_fBlob) {
dwType |= MST_THIS_BLOBSIGN;
}
else {
dwType |= MST_THIS_SIGN;
}
// M00HACK
// hr = InsertBody(pmm, HBODY_ROOT);
// if (FAILED(hr)) {
// goto exit;
// }
// Security Type
var.vt = VT_UI4;
var.ulVal = dwType;
hr = pmb->SetOption(OID_SECURITY_TYPE, &var);
if (FAILED(hr)) goto exit;
var.vt = VT_UI4;
var.ulVal = (DWORD) hcertstore;
hr = pmb->SetOption(OID_SECURITY_HCERTSTORE, &var);
if (FAILED(hr)) goto exit;
var.vt = VT_UI4;
var.ulVal = count;
hr = pmb->SetOption(OID_SECURITY_SIGNATURE_COUNT, &var);
if (FAILED(hr)) goto exit;
if (count > 1) {
var.vt = (VT_VECTOR | VT_VARIANT);
var.capropvar.cElems = count;
var.capropvar.pElems = rgpvAlgHash;
hr = pmb->SetOption(OID_SECURITY_ALG_HASH_RG, &var);
if (FAILED(hr)) goto exit;
var.vt = (VT_VECTOR | VT_UI4);
var.caul.cElems = count;
var.caul.pElems = (DWORD *) rgpccert;
hr = pmb->SetOption(OID_SECURITY_CERT_SIGNING_RG, &var);
if (FAILED(hr)) goto exit;
if (psmime2 == NULL) {
var.vt = (VT_VECTOR | VT_VARIANT);
var.capropvar.cElems = count;
var.capropvar.pElems = rgpvAuthAttr;
hr = pmb->SetOption(OID_SECURITY_AUTHATTR_RG, &var);
if (FAILED(hr)) goto exit;
}
}
else {
var.vt = VT_BLOB;
memcpy(&var.blob, &rgpvAlgHash[0].blob, sizeof(var.blob));
hr = pmb->SetOption(OID_SECURITY_ALG_HASH, &var);
if (FAILED(hr)) goto exit;
var.vt = VT_UI4;
var.ulVal = (ULONG) rgpccert[0];
hr = pmb->SetOption(OID_SECURITY_CERT_SIGNING, &var);
if (FAILED(hr)) goto exit;
if (psmime2 == NULL) {
var.vt = VT_BLOB;
memcpy(&var.blob, &rgpvAuthAttr[0].blob, sizeof(var.blob));
hr = pmb->SetOption(OID_SECURITY_AUTHATTR, &var);
if (FAILED(hr)) goto exit;
}
}
hr = S_OK;
exit:
CertCloseStore(hcertstore, 0);
if (pmb != NULL) pmb->Release();
if (psmime2 != NULL) psmime2->Release();
*pulLayers += 1;
return hr;
}
int CSignInfo::Count() const
{
int count = 0;
CSignData * psd;
for (psd=Head(); psd != NULL; psd = psd->Next()) {
count += 1;
}
return count;
}
//////////
CSignData::CSignData(int state) :
CItem(TYPE_SIGN_DATA, state)
{
m_pccert = NULL;
m_ulValidity = 0;
m_valLabel.cbData = 0;
m_valLabel.pbData = NULL;
m_fReceipt = FALSE;
m_fMLHistory = FALSE;
m_fAuthAttrib = FALSE;
m_fUnAuthAttrib = FALSE;
m_fLabel = FALSE;
m_valReceipt.cbData = 0;
m_valReceipt.pbData = NULL;
m_valMLHistory.cbData = 0;
m_valMLHistory.pbData = NULL;
m_valAuthAttrib.cbData = 0;
m_valAuthAttrib.pbData = NULL;
m_szAuthAttribOID = NULL;
m_valUnAuthAttrib.cbData = 0;
m_valUnAuthAttrib.pbData = NULL;
m_szUnAuthAttribOID = NULL;
}
HRESULT CSignData::BuildArrays(DWORD * pCount, DWORD * pdwType,
PROPVARIANT * rgvHash, PCCERT_CONTEXT * rgpccert,
PROPVARIANT * rgvAuthAttr, HCERTSTORE hcertstore,
IMimeSecurity2 * psmime2)
{
CRYPT_ATTRIBUTES attrs;
BOOL f;
int i = *pCount;
CRYPT_ATTRIBUTE rgattrs[4];
PROPVARIANT var;
*pdwType |= MST_THIS_SIGN;
rgvHash[i].blob.pBlobData = (LPBYTE) RgbSHA1AlgId;
rgvHash[i].blob.cbSize = CbSHA1AlgId;
// Don't add ref the certificate -- we don't free it in the caller.
rgpccert[i] = m_pccert;
f = CertAddCertificateContextToStore(hcertstore, m_pccert,
CERT_STORE_ADD_USE_EXISTING, NULL);
Assert(f);
// Setup for encoding authenticated attributes
attrs.cAttr = 0;
attrs.rgAttr = rgattrs;
// Encode in the label
if (m_valLabel.pbData != NULL) {
rgattrs[attrs.cAttr].pszObjId = szOID_SMIME_Security_Label;
rgattrs[attrs.cAttr].cValue = 1;
rgattrs[attrs.cAttr].rgValue = &m_valLabel;
if (psmime2 != NULL) {
psmime2->SetAttribute(0, i, SMIME_ATTRIBUTE_SET_SIGNED,
&rgattrs[attrs.cAttr]);
}
else {
attrs.cAttr += 1;
}
}
if (m_valReceipt.pbData != NULL) {
rgattrs[attrs.cAttr].pszObjId = szOID_SMIME_Receipt_Request;
rgattrs[attrs.cAttr].cValue = 1;
rgattrs[attrs.cAttr].rgValue = &m_valReceipt;
if (psmime2 != NULL) {
psmime2->SetAttribute(0, i, SMIME_ATTRIBUTE_SET_SIGNED,
&rgattrs[attrs.cAttr]);
}
else {
attrs.cAttr += 1;
}
}
if (m_valMLHistory.pbData != NULL) {
rgattrs[attrs.cAttr].pszObjId = szOID_SMIME_MLExpansion_History;
rgattrs[attrs.cAttr].cValue = 1;
rgattrs[attrs.cAttr].rgValue = &m_valMLHistory;
if (psmime2 != NULL) {
psmime2->SetAttribute(0, i, SMIME_ATTRIBUTE_SET_SIGNED,
&rgattrs[attrs.cAttr]);
}
else {
attrs.cAttr += 1;
}
}
if ((m_szAuthAttribOID != NULL) && (m_valAuthAttrib.pbData != NULL)) {
rgattrs[attrs.cAttr].pszObjId = m_szAuthAttribOID;
rgattrs[attrs.cAttr].cValue = 1;
rgattrs[attrs.cAttr].rgValue = &m_valAuthAttrib;
if (psmime2 != NULL) {
psmime2->SetAttribute(0, i, SMIME_ATTRIBUTE_SET_SIGNED,
&rgattrs[attrs.cAttr]);
}
else {
attrs.cAttr += 1;
}
}
if (psmime2 != NULL) {
if ((m_szUnAuthAttribOID != NULL) && (m_valUnAuthAttrib.pbData != NULL)) {
rgattrs[attrs.cAttr].pszObjId = m_szUnAuthAttribOID;
rgattrs[attrs.cAttr].cValue = 1;
rgattrs[attrs.cAttr].rgValue = &m_valUnAuthAttrib;
psmime2->SetAttribute(0, i, SMIME_ATTRIBUTE_SET_UNSIGNED,
&rgattrs[attrs.cAttr]);
}
}
Assert(attrs.cAttr <= sizeof(rgattrs)/sizeof(rgattrs[0]));
if (attrs.cAttr > 0) {
f = CryptEncodeObjectEx(X509_ASN_ENCODING, szOID_Microsoft_Attribute_Sequence,
&attrs, CRYPT_ENCODE_ALLOC_FLAG, NULL,
&rgvAuthAttr[i].blob.pBlobData,
&rgvAuthAttr[i].blob.cbSize);
Assert(f);
}
*pCount = i+1;
return S_OK;
}
void CSignData::SetLabel(LPBYTE pb, DWORD cb)
{
if (m_valLabel.pbData != NULL) {
free(m_valLabel.pbData);
m_valLabel.pbData = NULL;
m_valLabel.cbData = 0;
}
if (cb > 0) {
m_valLabel.pbData = (LPBYTE) malloc(cb);
memcpy(m_valLabel.pbData, pb, cb);
m_valLabel.cbData = cb;
}
}