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
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;
|
|
}
|
|
}
|
|
|
|
|