PGPError PGPX509CertToExport( PGPContextRef context, PGPKeyRef keyCert, PGPSigRef sigCert, PGPUInt32* puX509Alg, PGPByte* pexpkeyidX509, PGPByte** ppIASNX509, PGPUInt32* puX509IASNLength ) { PGPError err = kPGPError_NoErr; PGPSize size; PGPKeyID keyid; PGPValidatePtr (puX509Alg); PGPValidatePtr (pexpkeyidX509); PGPValidatePtr (ppIASNX509); PGPValidatePtr (puX509IASNLength); *puX509Alg = kPGPPublicKeyAlgorithm_Invalid; *ppIASNX509 = NULL; *puX509IASNLength = 0; if (PGPKeyRefIsValid (keyCert)) { err = PGPGetKeyNumber (keyCert, kPGPKeyPropAlgID, (PGPInt32 *)puX509Alg); CKERR; err = PGPGetKeyIDFromKey (keyCert, &keyid); CKERR; err = PGPExportKeyID (&keyid, pexpkeyidX509, &size); CKERR; PGPGetSigPropertyBuffer (sigCert, kPGPSigPropX509IASN, 0, NULL, (PGPSize *)puX509IASNLength); if (*puX509IASNLength > 0) { *ppIASNX509 = (PGPByte *)PGPNewData ( PGPGetContextMemoryMgr (context), *puX509IASNLength, kPGPMemoryMgrFlags_Clear ); if (*ppIASNX509) { PGPGetSigPropertyBuffer (sigCert, kPGPSigPropX509IASN, *puX509IASNLength, *ppIASNX509, &size); } } } done: return err; }
static PGPError sAddAllKeysToGroup( PGPGroupSetRef set, PGPGroupID id, PGPKeySetRef keySet ) { PGPError err = kPGPError_NoErr; PGPKeyListRef keyList; err = PGPOrderKeySet( keySet, kPGPAnyOrdering, &keyList ); if( IsntPGPError( err ) ) { PGPKeyIterRef iter; err = PGPNewKeyIter( keyList, &iter ); if( IsntPGPError( err ) ) { PGPKeyRef key; while( IsntPGPError( err = PGPKeyIterNext( iter, &key ) ) ) { PGPKeyID keyID; err = PGPGetKeyIDFromKey( key, &keyID ); if ( IsntPGPError( err ) ) { PGPGroupItem item; PGPInt32 algorithm; item.type = kPGPGroupItem_KeyID; item.u.key.keyID = keyID; PGPGetKeyNumber( key, kPGPKeyPropAlgID, &algorithm); item.u.key.algorithm = (PGPPublicKeyAlgorithm) algorithm; err = PGPAddItemToGroup( set, &item, id); if ( IsPGPError( err ) ) break; } } if( err == kPGPError_EndOfIteration ) err = kPGPError_NoErr; (void) PGPFreeKeyIter( iter ); } (void) PGPFreeKeyList( keyList ); } return( err ); }
PGPError printSignatureChains(struct pgpmainBones *mainbPtr, PGPKeySetRef bothRingsSet, PGPFilterRef depthFilter) { struct pgpfileBones *filebPtr = mainbPtr->filebPtr; PGPKeyListRef depthList; PGPKeySetRef depthSet; PGPKeyRef key; PGPKeyIterRef keyiter; PGPKeyID keyID; PGPUserValue traceValue; PGPError err; char useridstr[ kPGPMaxUserIDSize ]; char nulluseridstr[kPGPMaxUserIDSize]; nulluseridstr[0] = '\0'; err = PGPFilterKeySet( bothRingsSet, depthFilter, &depthSet); pgpAssertNoErr(err); err = PGPOrderKeySet(depthSet, kPGPAnyOrdering, &depthList); pgpAssertNoErr(err); err = PGPNewKeyIter( depthList, &keyiter ); pgpAssertNoErr(err); err = PGPKeyIterRewind( keyiter ); pgpAssertNoErr(err); err = PGPKeyIterNext( keyiter, &key ); while (key != NULL) { err = pgpGetUserIDStringFromKey( key, useridstr ); pgpAssertNoErr(err); fprintf(filebPtr->pgpout, LANG("* %s\n"), useridstr); err = PGPGetKeyIDFromKey( key, &keyID); pgpAssertNoErr(err); traceValue = (PGPUserValue)( VISITED_MASK | 0 ); err = PGPSetKeyUserVal(key, traceValue); pgpAssertNoErr(err); err = printNextSignatureChainLink(mainbPtr, bothRingsSet, key, 0, 1); pgpAssertNoErr(err); err = PGPKeyIterNext( keyiter, &key ); } return 0; } /* printSignatureChains */
BOOL KMSplitDropKeys ( PSPLITKEYSTRUCT psks, HANDLE hMem) { PGPKeySetRef keyset = NULL; PGPKeyListRef keylist = NULL; PGPKeyIterRef keyiter = NULL; LPSTR pMem = NULL; PGPError err; PGPKeyRef key; PGPKeyID keyid; BOOL bKeys; PGPBoolean bKeyIsUsable; size_t sLen; PSHAREHOLDERSTRUCT pshs; PGPPublicKeyAlgorithm alg; bKeys = FALSE; if (hMem) { pMem = GlobalLock (hMem); if (pMem) { sLen = lstrlen (pMem); err = PGPImportKeySet (psks->pKM->Context, &keyset, PGPOInputBuffer (psks->pKM->Context, pMem, sLen), PGPOLastOption (psks->pKM->Context)); if (IsPGPError (err)) goto SplitDropCleanup; err = PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist); if (IsPGPError (err)) goto SplitDropCleanup; err = PGPNewKeyIter (keylist, &keyiter); if (IsPGPError (err)) goto SplitDropCleanup; PGPKeyIterNext (keyiter, &key); while (key) { bKeyIsUsable = FALSE; PGPGetKeyNumber (key, kPGPKeyPropAlgID, &alg); PGPGetKeyIDFromKey (key, &keyid); // key must either not be RSA or RSA ops must be enabled PGPGetKeyBoolean (key, kPGPKeyPropCanEncrypt, &bKeyIsUsable); // key must not be the same one that is being split if (alg == psks->keyalgToSplit) { if (PGPCompareKeyIDs (&keyid, &(psks->keyidToSplit))==0) bKeyIsUsable = FALSE; } // key must not already be in list if (sIsKeyIDAlreadyInList (&keyid, alg, psks)) bKeyIsUsable = FALSE; if (bKeyIsUsable) { bKeys = TRUE; pshs = KMAlloc (sizeof(SHAREHOLDERSTRUCT)); if (pshs) { PGPSize size; pshs->bPublicKey = TRUE; pshs->pszPassphrase = NULL; pshs->uShares = 1; PGPGetPrimaryUserIDNameBuffer (key, sizeof(pshs->szUserID), pshs->szUserID, &size); PGPGetKeyIDFromKey (key, &(pshs->keyid)); PGPGetKeyNumber (key, kPGPKeyPropAlgID, &(pshs->keyalg)); if (sAddShareHolder (psks, pshs, KMDetermineUserIDIcon (key, NULL, NULL), psks->hwndList)) { psks->uTotalShares += pshs->uShares; SetDlgItemInt (psks->hwndDlg, IDC_TOTALSHARES, psks->uTotalShares, FALSE); SendMessage (psks->hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_THRESHOLD, EN_CHANGE), 0); } else { KMFree (pshs); } } } PGPKeyIterNext (keyiter, &key); } SplitDropCleanup : if (keyiter) PGPFreeKeyIter (keyiter); if (keylist) PGPFreeKeyList (keylist); if (keyset) PGPFreeKeySet (keyset); if (pMem) GlobalUnlock (hMem); } } return bKeys; }
BOOL KMSplitKey (PKEYMAN pKM, PGPKeyRef key) { PSPLITKEYSTRUCT psks; BOOL bOK; PGPKeyID keyidToSplit; PGPPublicKeyAlgorithm keyalgToSplit; HWND hwnd; // find existing dialog struct for this key PGPGetKeyIDFromKey (key, &keyidToSplit); PGPGetKeyNumber (key, kPGPKeyPropAlgID, &keyalgToSplit); psks = pKM->pSplitKeyDialogList; while (psks) { if (PGPCompareKeyIDs (&keyidToSplit, &(psks->keyidToSplit)) == 0) { if (keyalgToSplit == psks->keyalgToSplit) break; } psks = psks->next; } // if dialog already exists, move to foreground if (psks) { SetForegroundWindow (psks->hwndDlg); bOK = TRUE; } // otherwise create new dialog else { psks = KMAlloc (sizeof (SPLITKEYSTRUCT)); if (psks) { // initialize struct psks->pKM = pKM; psks->pHeadOfList = &(pKM->pSplitKeyDialogList); PGPGetKeyIDFromKey (key, &(psks->keyidToSplit)); psks->keyalgToSplit = keyalgToSplit; KMGetKeyName (key, psks->szUserIDToSplit, kPGPMaxUserIDSize); psks->uTotalShares = 0; psks->uThreshold = 2; psks->iIndexCurrent = -1; psks->pshsCurrent = NULL; psks->pDropTarget = NULL; // create modeless dialog hwnd = CreateDialogParam (g_hInst, MAKEINTRESOURCE (IDD_SPLITKEY), NULL, sSplitKeyDlgProc, (LPARAM)psks); // make it "floating" SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); // add dialog struct to list psks->next = pKM->pSplitKeyDialogList; pKM->pSplitKeyDialogList = psks; bOK = TRUE; } else bOK = FALSE; } return bOK; }
PVOID __cdecl _pgp_select_keyid(HWND hDlg,LPSTR szKeyID) { #if (PGP_WIN32 < 0x700) PGPKeySetRef ContactKeyDB; #else PGPKeyDBRef ContactKeyDB; #endif PGPError err; err = PGPRecipientDialog(pgpContext, pgpKeyDB, TRUE, &ContactKeyDB, PGPOUIParentWindowHandle(pgpContext, hDlg), PGPOUIWindowTitle(pgpContext, "Select Contact's Key"), PGPOLastOption(pgpContext)); if (err == kPGPError_UserAbort) return 0; PGPUInt32 dwKeys; #if (PGP_WIN32 < 0x700) PGPCountKeys(ContactKeyDB, &dwKeys); #else PGPCountKeysInKeyDB(ContactKeyDB, &dwKeys); #endif if (!dwKeys) { return 0; } else if (dwKeys > 1) MessageBox(hDlg, "You selected more than one key. Only the first key will be used.", szModuleName, MB_ICONINFORMATION); static PGPKeyID KeyID; #if (PGP_WIN32 < 0x700) PGPKeyListRef ContactKeyList; PGPOrderKeySet(ContactKeyDB, kPGPKeyIDOrdering, &ContactKeyList); PGPKeyIterRef KeyIterRef; PGPNewKeyIter(ContactKeyList, &KeyIterRef); PGPKeyRef ContactKey; PGPKeyIterNext(KeyIterRef, &ContactKey); PGPGetKeyIDFromKey(ContactKey, &KeyID); PGPGetKeyIDString(&KeyID, kPGPKeyIDString_Abbreviated, szKeyID); PGPFreeKeyList(ContactKeyList); PGPFreeKeyIter(KeyIterRef); PGPFreeKeySet(ContactKeyDB); #else PGPKeyIterRef KeyIterRef; PGPNewKeyIterFromKeyDB(ContactKeyDB, &KeyIterRef); PGPKeyDBObjRef KeyDBObjRef; PGPKeyIterNextKeyDBObj(KeyIterRef, kPGPKeyDBObjType_Key, &KeyDBObjRef); PGPSize dwFilled; PGPGetKeyDBObjDataProperty(KeyDBObjRef, kPGPKeyProperty_KeyID, &KeyID, sizeof(PGPKeyID), &dwFilled); PGPGetKeyIDString(&KeyID, kPGPKeyIDString_Abbreviated, szKeyID); PGPFreeKeyIter(KeyIterRef); PGPFreeKeyDB(ContactKeyDB); #endif return (PVOID)&KeyID; }
PGPError PGPclExport PGPclUpdateKeySetFromServer ( PGPContextRef context, PGPtlsContextRef tlsContext, HWND hwndParent, PGPKeySetRef keysetToUpdate, UINT uServer, PGPKeySetRef keysetMain, PGPKeySetRef* pkeysetResult) { PGPError err = kPGPError_NoErr; PGPKeySetRef keysetCollect = kInvalidPGPKeySetRef; PGPOptionListRef optionSearch = kInvalidPGPOptionListRef; PGPKeyListRef keylist = kInvalidPGPKeyListRef; PGPKeyIterRef keyiter = kInvalidPGPKeyIterRef; PGPKeySetRef keyset = kInvalidPGPKeySetRef; PGPKeyID keyid; // initialize return keyset PGPValidatePtr (pkeysetResult); *pkeysetResult = kInvalidPGPKeySetRef; if (uServer == PGPCL_USERIDBASEDSERVER) { PGPKeyRef key = kInvalidPGPKeyRef; CHAR szUserID[kPGPMaxUserIDSize+1]; PGPSize size; err = PGPNewKeySet (context, &keysetCollect); CKERR; err = PGPOrderKeySet (keysetToUpdate, kPGPAnyOrdering, &keylist); CKERR; err = PGPNewKeyIter (keylist, &keyiter); CKERR; while ( IsntPGPError (err) && IsntPGPError (PGPKeyIterNext (keyiter, &key)) && PGPKeyRefIsValid (key)) { err = PGPGetPrimaryUserIDNameBuffer (key, kPGPMaxUserIDSize, szUserID, &size); CKERR; err = PGPGetKeyIDFromKey (key, &keyid); CKERR; optionSearch = PGPOUIKeyServerSearchKeyIDList (context, 1, &keyid); if (PGPOptionListRefIsValid (optionSearch)) { err = sQueryServerInternal (hwndParent, context, tlsContext, optionSearch, uServer, szUserID, keysetMain, &keyset); if (IsPGPError (PGPclErrorBox (hwndParent, err))) err = kPGPError_NoErr; if (IsntPGPError (err)) { if (PGPKeySetRefIsValid (keyset)) { err = PGPAddKeys (keyset, keysetCollect); if (IsntPGPError (PGPclErrorBox (hwndParent, err))) { err = PGPCommitKeyRingChanges (keysetCollect); PGPclErrorBox (hwndParent, err); } } } if (PGPKeySetRefIsValid (keyset)) { PGPFreeKeySet (keyset); keyset = kInvalidPGPKeySetRef; } } } if (PGPKeySetRefIsValid (keysetCollect)) { *pkeysetResult = keysetCollect; keysetCollect = kInvalidPGPKeySetRef; } } else { optionSearch = PGPOUIKeyServerSearchKeySet (context, keysetToUpdate); if (PGPOptionListRefIsValid (optionSearch)) { err = sQueryServerInternal (hwndParent, context, tlsContext, optionSearch, uServer, "", keysetMain, &keysetCollect); if (IsntPGPError (err)) { *pkeysetResult = keysetCollect; keysetCollect = kInvalidPGPKeySetRef; } } } done : if (PGPKeyListRefIsValid (keylist)) PGPFreeKeyList (keylist); if (PGPKeyIterRefIsValid (keyiter)) PGPFreeKeyIter (keyiter); if (PGPKeySetRefIsValid (keyset)) PGPFreeKeySet (keyset); if (PGPKeySetRefIsValid (keysetCollect)) PGPFreeKeySet (keysetCollect); return err; }
PGPError findUltimatelyTrustedKeys(struct pgpmainBones *mainbPtr, PGPKeySetRef secRingSet, PGPKeySetRef bothRingsSet, PGPFilterRef *depthFilter) { struct pgpfileBones *filebPtr = mainbPtr->filebPtr; PGPKeyIterRef keyiter; PGPKeyRef skey; PGPKeyListRef secKeylist; PGPKeyListRef bothKeylist; PGPError err; PGPUInt32 trust; PGPBoolean compatible = mainbPtr->envbPtr->compatible; char kstr[kPGPMaxKeyIDStringSize]; char useridstr[ kPGPMaxUserIDSize ]; PGPContextRef context = mainbPtr->pgpContext; PGPKeyID kid; PGPBoolean firstUltimatelyTrustedKey = TRUE; PGPFilterRef singletonFilter = NULL; /* Pass 1: locate ultimately-trusted keys. */ fprintf(filebPtr->pgpout, LANG("\nPass 1: Looking for the \"ultimately-trusted\" keys...\n")); err = PGPOrderKeySet( secRingSet, kPGPAnyOrdering, &secKeylist ); if( IsPGPError(err) ) return -1; err = PGPOrderKeySet( bothRingsSet, kPGPAnyOrdering, &bothKeylist ); if( IsPGPError(err) ) return -1; err = PGPNewKeyIter( secKeylist, &keyiter ); pgpAssertNoErr(err); err = PGPKeyIterRewind( keyiter ); pgpAssertNoErr(err); err = PGPKeyIterNext( keyiter, &skey); /*if error, no keys found.*/ if (err) { fprintf(filebPtr->pgpout, LANG("No ultimately-trusted keys.") ); return err; } while( skey != NULL ) { err = PGPGetKeyNumber( skey, kPGPKeyPropTrust, &trust); pgpAssertNoErr(err); if (trust == kPGPKeyTrust_Ultimate) { err = pgpGetKeyIDStringCompatFromKey( skey, TRUE, compatible, kstr ); pgpAssertNoErr(err); err = pgpGetUserIDStringFromKey( skey, useridstr ); pgpAssertNoErr(err); /* '*' means axiomatically trusted. */ fprintf(filebPtr->pgpout, LANG("* %s %s\n") ,kstr,useridstr); /* Make filter for depth 0 (=ultimately-trusted) keys. */ err = PGPGetKeyIDFromKey (skey, &kid); pgpAssertNoErr(err); if (firstUltimatelyTrustedKey) { err = PGPNewKeyIDFilter( context, &kid, depthFilter ); pgpAssertNoErr(err); firstUltimatelyTrustedKey = FALSE; } else { err = PGPNewKeyIDFilter( context, &kid, &singletonFilter ); pgpAssertNoErr(err); err = PGPUnionFilters ( singletonFilter, *depthFilter, depthFilter ); pgpAssertNoErr(err); } } err = PGPKeyIterNext( keyiter, &skey); } err = PGPFreeKeyList( bothKeylist ); pgpAssertNoErr(err); err = PGPFreeKeyList( secKeylist ); pgpAssertNoErr(err); return 0; } /* findUltimatelyTrustedKeys */
PGPError printNextSignatureChainLink(struct pgpmainBones *mainbPtr, PGPKeySetRef bothRingsSet, PGPKeyRef key, PGPBoolean visited, PGPUInt32 currentDepth) { PGPContextRef context = mainbPtr->pgpContext; struct pgpfileBones *filebPtr = mainbPtr->filebPtr; PGPUserValue traceValue; PGPUInt32 keyDepth; PGPKeyListRef kidsList; PGPKeySetRef kidsSet; PGPFilterRef kidsFilter; PGPFilterRef singletonFilter; PGPFilterRef notParentFilter; PGPKeyIterRef keyIter; char useridstr[kPGPMaxUserIDSize]; PGPError err = kPGPError_NoErr; PGPKeyID keyID; /* For first time at node? Create keyset containing its children. */ if (!visited) { err = PGPGetKeyIDFromKey( key, &keyID); pgpAssertNoErr(err); err = PGPNewSigKeyIDFilter(context, &keyID, &kidsFilter); pgpAssertNoErr(err); err = PGPNewKeyIDFilter( context, &keyID, &singletonFilter ); pgpAssertNoErr(err); err = PGPNegateFilter( singletonFilter, ¬ParentFilter); pgpAssertNoErr(err); err = PGPIntersectFilters( notParentFilter, kidsFilter, &kidsFilter ); pgpAssertNoErr(err); if (kidsFilter == NULL) return 0; /* childless node */ err = PGPFilterKeySet(bothRingsSet, kidsFilter, &kidsSet); pgpAssertNoErr(err); err = PGPOrderKeySet( kidsSet, kPGPAnyOrdering, &kidsList); pgpAssertNoErr(err); err = PGPNewKeyIter(kidsList, &keyIter); pgpAssertNoErr(err); err = PGPKeyIterRewind( keyIter); pgpAssertNoErr(err); err = PGPKeyIterNext( keyIter, &key); if (IsPGPError(err)) { /* childless */ PGPFreeKeyIter( keyIter); return 0; } } while (key != NULL) { err = PGPGetKeyUserVal(key, &traceValue); pgpAssertNoErr(err); visited = (PGPUInt32)traceValue & VISITED_MASK; keyDepth = (PGPUInt32)traceValue & DEPTH_MASK; err = pgpGetUserIDStringFromKey(key, useridstr); pgpAssertNoErr(err); fprintf(filebPtr->pgpout, LANG("%*s"), (2 * currentDepth), " "); fprintf(filebPtr->pgpout, LANG("> %s\n"), useridstr); if (visited || (keyDepth < currentDepth) ) return 0; traceValue = (PGPUserValue)( VISITED_MASK | keyDepth); err = PGPSetKeyUserVal(key, traceValue); pgpAssertNoErr(err); err = PGPGetKeyIDFromKey( key, &keyID); pgpAssertNoErr(err); err = printNextSignatureChainLink(mainbPtr, bothRingsSet, key, visited, currentDepth+1); err = PGPKeyIterNext( keyIter, &key ); if ( IsPGPError(err) ) { /* traversed all children of this node */ PGPFreeKeyIter( keyIter); return 0; } } return err; } /* printNextSignatureChainLink */
PGPError markSignatureChainDepths(struct pgpmainBones *mainbPtr, PGPKeySetRef bothRingsSet, PGPFilterRef depthFilter) { struct pgpfileBones *filebPtr = mainbPtr->filebPtr; PGPContextRef context = mainbPtr->pgpContext; PGPBoolean compatible = mainbPtr->envbPtr->compatible; PGPKeyIterRef keyiter; PGPKeyID kid; PGPKeySetRef depthSet; PGPKeyListRef depthList; PGPKeyRef key; PGPFilterRef signedByMeFilter = NULL; PGPFilterRef usedKeysFilter = NULL; PGPFilterRef unusedKeysFilter = NULL; char kstr[kPGPMaxKeyIDStringSize]; char useridstr[ kPGPMaxUserIDSize ]; PGPError err; PGPBoolean firstKeyAtThisDepth; PGPUInt32 depth = 0; PGPUInt32 count; PGPUserValue traceValue; /* Trace value contains highest depth in sig chain where this key appears. High bit ='visited' flag - indicates if chain has been followed from this point. */ fprintf(filebPtr->pgpout, LANG("\nPass 2: Tracing signature chains...\n")); usedKeysFilter = depthFilter; err = PGPNegateFilter( usedKeysFilter, &unusedKeysFilter ); pgpAssertNoErr(err); err = PGPFilterKeySet( bothRingsSet, depthFilter, &depthSet); pgpAssertNoErr(err); err = PGPCountKeys( depthSet, &count); pgpAssertNoErr(err); if (count == 0) { fprintf(filebPtr->pgpout, LANG("No ultimately-trusted keys.") ); return -1; } while ( TRUE ) { firstKeyAtThisDepth = TRUE; err = PGPOrderKeySet(depthSet, kPGPAnyOrdering, &depthList); pgpAssertNoErr(err); err = PGPNewKeyIter( depthList, &keyiter ); pgpAssertNoErr(err); err = PGPKeyIterRewind( keyiter ); pgpAssertNoErr(err); err = PGPKeyIterNext( keyiter, &key); while( key != NULL ) { err = pgpGetKeyIDStringCompatFromKey( key, TRUE, compatible, kstr ); pgpAssertNoErr(err); err = pgpGetUserIDStringFromKey( key, useridstr ); pgpAssertNoErr(err); /* Mark its highest depth level on each key. */ err = PGPGetKeyUserVal( key, &traceValue); pgpAssertNoErr(err); if ( (PGPUInt32)traceValue == 0) { (PGPUInt32)traceValue = depth; err = PGPSetKeyUserVal( key, traceValue); pgpAssertNoErr(err); } err = PGPGetKeyIDFromKey( key, &kid ); pgpAssertNoErr(err); if (firstKeyAtThisDepth) { err = PGPNewSigKeyIDFilter(context, &kid, &depthFilter); pgpAssertNoErr(err); firstKeyAtThisDepth = FALSE; } else { err = PGPNewSigKeyIDFilter(context, &kid, &signedByMeFilter); pgpAssertNoErr(err); err = PGPUnionFilters( signedByMeFilter, depthFilter, &depthFilter); pgpAssertNoErr(err); } err = PGPKeyIterNext( keyiter, &key); } err = PGPIntersectFilters(unusedKeysFilter, depthFilter, &depthFilter); pgpAssertNoErr(err); /* Create next depth level. */ err = PGPFreeKeySet( depthSet ); pgpAssertNoErr(err); err = PGPFilterKeySet( bothRingsSet, depthFilter, &depthSet); pgpAssertNoErr(err); err = PGPCountKeys( depthSet, &count); pgpAssertNoErr(err); err = PGPFreeKeyIter( keyiter ); pgpAssertNoErr(err); if (count == 0) return 0; err = PGPUnionFilters( depthFilter, usedKeysFilter, &usedKeysFilter); pgpAssertNoErr(err); err = PGPNegateFilter( usedKeysFilter, &unusedKeysFilter ); pgpAssertNoErr(err); depth ++; } } /* markSignatureChainDepths */
void ShowKeyring(HWND hWnd, int nListCtrl, PGPContextRef pgpContext, PGPKeySetRef onlyThisKeySet, PGPBoolean bShowRSA, PGPBoolean bShowDH, PGPBoolean bMustEncrypt, PGPBoolean bMustSign) { PGPKeyRef newKey = NULL; PGPKeyID newKeyID; PGPSubKeyRef newSubKey = NULL; PGPError err; PGPKeySetRef userKeySet = NULL; PGPKeyListRef klist; PGPKeyIterRef kiter; unsigned char szUserID[kPGPMaxUserIDSize+1]; char szTempKeyID[kPGPMaxKeyIDStringSize+1]; char szSize[64]; char szCreation[64]; char szTitle[255]; UINT nLength; HWND hList; HDC hDC; int iNumBits; LV_ITEM lviKey; LV_COLUMN lvcKey; UINT nItem; HIMAGELIST hImages; HBITMAP hBmp; PGPInt32 nSignSize; PGPInt32 nEncryptSize; PGPTime tCreation; PGPUInt16 year, month, day; PGPBoolean bIsRevoked; PGPBoolean bIsDisabled; PGPBoolean bIsExpired; PGPBoolean bIsEncryptKey; PGPBoolean bIsSigningKey; PGPPublicKeyAlgorithm lAlg; if(IsPGPError(err = PGPOpenDefaultKeyRings(pgpContext, (PGPKeyRingOpenFlags) 0, &userKeySet))) { MessageBox(NULL, "PGPOpenDefaultKeyRings error", "debug", MB_OK); return; } hList = GetDlgItem(hWnd, nListCtrl); ListView_DeleteAllItems(hList); ListView_DeleteColumn(hList, 2); ListView_DeleteColumn(hList, 1); ListView_DeleteColumn(hList, 0); hDC = GetDC (NULL); // DC for desktop iNumBits = GetDeviceCaps (hDC, BITSPIXEL) * GetDeviceCaps (hDC, PLANES); ReleaseDC (NULL, hDC); if (iNumBits <= 8) { hImages = ImageList_Create (16, 16, ILC_COLOR | ILC_MASK, NUM_BITMAPS, 0); hBmp = LoadBitmap (g_hInstance, MAKEINTRESOURCE (IDB_IMAGES4BIT)); ImageList_AddMasked (hImages, hBmp, RGB(255, 0, 255)); DeleteObject (hBmp); } else { hImages = ImageList_Create (16, 16, ILC_COLOR24 | ILC_MASK, NUM_BITMAPS, 0); hBmp = LoadBitmap (g_hInstance, MAKEINTRESOURCE (IDB_IMAGES24BIT)); ImageList_AddMasked (hImages, hBmp, RGB(255, 0, 255)); DeleteObject (hBmp); } ListView_SetImageList(hList, hImages, LVSIL_SMALL); // Setup the list control columns LoadString(g_hInstance, IDS_USERID, szTitle, 254); lvcKey.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; lvcKey.fmt = LVCFMT_LEFT; lvcKey.cx = 175; lvcKey.pszText = szTitle; lvcKey.iSubItem = -1; ListView_InsertColumn(hList, 0, &lvcKey); LoadString(g_hInstance, IDS_CREATION, szTitle, 254); lvcKey.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; lvcKey.fmt = LVCFMT_CENTER; lvcKey.cx = 75; lvcKey.pszText = szTitle; lvcKey.iSubItem = 1; ListView_InsertColumn(hList, 1, &lvcKey); LoadString(g_hInstance, IDS_KEYSIZE, szTitle, 254); lvcKey.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; lvcKey.fmt = LVCFMT_CENTER; lvcKey.cx = 75; lvcKey.pszText = szTitle; lvcKey.iSubItem = 2; ListView_InsertColumn(hList, 2, &lvcKey); /* Initialize keyrings */ PGPOrderKeySet(userKeySet, kPGPUserIDOrdering, &klist); PGPNewKeyIter(klist, &kiter); PGPKeyIterNext(kiter, &newKey); nItem = 0; while (newKey) { PGPGetKeyBoolean(newKey, kPGPKeyPropIsRevoked, &bIsRevoked); PGPGetKeyBoolean(newKey, kPGPKeyPropIsDisabled, &bIsDisabled); PGPGetKeyBoolean(newKey, kPGPKeyPropIsExpired, &bIsExpired); PGPGetKeyBoolean(newKey, kPGPKeyPropIsEncryptionKey, &bIsEncryptKey); PGPGetKeyBoolean(newKey, kPGPKeyPropIsSigningKey, &bIsSigningKey); if ((bIsRevoked || bIsDisabled || bIsExpired) || (!bIsEncryptKey && bMustEncrypt) || (!bIsSigningKey && bMustSign)) { PGPKeyIterNext(kiter, &newKey); continue; } PGPGetKeyNumber(newKey, kPGPKeyPropAlgID, (PGPInt32 *) &lAlg); if ((bShowRSA && (lAlg == kPGPPublicKeyAlgorithm_RSA)) || (bShowDH && (lAlg == kPGPPublicKeyAlgorithm_DSA))) { if (IsPGPError(PGPGetPrimaryUserIDNameBuffer(newKey, kPGPMaxUserIDSize, (char*)szUserID, &nLength))) { PGPKeyIterNext(kiter, &newKey); continue; } szUserID[nLength] = 0; if (IsPGPError(PGPGetKeyNumber(newKey, kPGPKeyPropBits, &nSignSize))) { PGPKeyIterNext(kiter, &newKey); continue; } if (lAlg == kPGPPublicKeyAlgorithm_DSA) { PGPKeyIterNextSubKey(kiter, &newSubKey); if (newSubKey) { if (IsPGPError(PGPGetSubKeyNumber(newSubKey, kPGPKeyPropBits, &nEncryptSize))) { PGPKeyIterNext(kiter, &newKey); continue; } wsprintf(szSize, "%d/%d", nEncryptSize, nSignSize); } else wsprintf(szSize, "%d", nSignSize); } else wsprintf(szSize, "%d", nSignSize); if (IsPGPError(PGPGetKeyTime(newKey, kPGPKeyPropCreation, &tCreation))) { PGPKeyIterNext(kiter, &newKey); continue; } PGPGetYMDFromPGPTime(tCreation, &year, &month, &day); wsprintf(szCreation, "%d/%d/%d", month, day, year); if (onlyThisKeySet != NULL) { if (!PGPKeySetIsMember(newKey, onlyThisKeySet)) { PGPKeyIterNext(kiter, &newKey); continue; } } PGPGetKeyIDFromKey(newKey, &newKeyID); PGPGetKeyIDString(&newKeyID, kPGPKeyIDString_Full, szTempKeyID); lviKey.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; lviKey.pszText = (char *) szUserID; lviKey.iItem = nItem; lviKey.iSubItem = 0; if (lAlg == kPGPPublicKeyAlgorithm_RSA) lviKey.iImage = IDX_RSAPUBKEY; if (lAlg == kPGPPublicKeyAlgorithm_DSA) lviKey.iImage = IDX_DSAPUBKEY; lviKey.lParam = (long) pgpAlloc(strlen(szTempKeyID)+1); strcpy((char *) lviKey.lParam, szTempKeyID); ListView_InsertItem(hList, &lviKey); lviKey.mask = LVIF_TEXT; lviKey.pszText = szCreation; lviKey.iItem = nItem; lviKey.iSubItem = 1; ListView_SetItem(hList, &lviKey); lviKey.mask = LVIF_TEXT; lviKey.pszText = szSize; lviKey.iItem = nItem; lviKey.iSubItem = 2; ListView_SetItem(hList, &lviKey); nItem++; } PGPKeyIterNext(kiter, &newKey); } PGPFreeKeyIter( kiter ); PGPFreeKeyList( klist ); /* Everything was OK */ err = kPGPError_NoErr; PGPFreeKeySet(userKeySet); return; }
PGPError PGPclExport PGPclGetCachedSigningPhrase ( PGPContextRef context, PGPtlsContextRef tlsContext, HWND hwnd, LPSTR szPrompt, BOOL bForceUserInput, LPSTR* pszBuffer, PGPKeySetRef keysetSigning, PGPKeyRef* pkeySigning, PGPHashAlgorithm* pulHashAlg, UINT* puOptions, UINT uFlags, PGPByte** ppPasskeyBuffer, PGPUInt32* piPasskeyLength, PGPKeySetRef* pkeysetAdded, char * szTitle) { PGPBoolean bCacheEnabled = FALSE; PGPUInt32 uCacheSecs = 0; PGPError err = kPGPError_NoErr; PGPBoolean bWarnRSADSA = FALSE; BOOL bAskUser = TRUE; PGPSize size; PGPPrefRef prefref; PGPKeyID keyid; DWORD dw; // Get needed preferences err = PGPclOpenClientPrefs (PGPGetContextMemoryMgr (context), &prefref); if (IsntPGPError (err)) { PGPGetPrefBoolean (prefref, kPGPPrefSignCacheEnable, &bCacheEnabled); PGPGetPrefNumber (prefref, kPGPPrefSignCacheSeconds, &uCacheSecs); // Need a never show again box? PGPGetPrefBoolean (prefref, kPGPPrefWarnOnRSARecipAndNonRSASigner, &bWarnRSADSA); PGPclCloseClientPrefs (prefref, FALSE); } EnterCriticalSection (&criticalSectionCache); // use phrase from cache if (!bForceUserInput && bCacheEnabled && sIsCacheValid (&cacheSigning)) { err = kPGPError_NoErr; if (bWarnRSADSA && (cacheSigning.CachedKeyAlg != kPGPPublicKeyAlgorithm_RSA) && (uFlags & PGPCL_RSAENCRYPT)) { PGPBoolean bNeverShowAgain = FALSE; err = PGPclRSADSAMixWarning (hwnd, &bNeverShowAgain); switch (err) { case kPGPError_NoErr : bAskUser = TRUE; if (bNeverShowAgain) { err = PGPclOpenClientPrefs ( PGPGetContextMemoryMgr (context), &prefref); if (IsntPGPError (err)) { PGPSetPrefBoolean (prefref, kPGPPrefWarnOnRSARecipAndNonRSASigner, FALSE); PGPclCloseClientPrefs (prefref, TRUE); } } break; case kPGPError_UserAbort : bAskUser = FALSE; break; } } if (err == kPGPError_NoErr) { // reset cache duration sSetCacheDuration (&cacheSigning, uCacheSecs); // see if cached key is in keyset if (pkeySigning) { err = PGPImportKeyID (&cacheSigning.CachedKeyID, &keyid); if (IsntPGPError (err)) { // if so, get keyref for this keyid err = PGPGetKeyByKeyID (keysetSigning, &keyid, kPGPPublicKeyAlgorithm_Invalid, pkeySigning); if (IsPGPError (err)) *pkeySigning = NULL; } err = sCopyCache (&cacheSigning, context, pszBuffer, ppPasskeyBuffer, piPasskeyLength); if (pulHashAlg) *pulHashAlg = cacheSigning.CachedHashAlg; if (puOptions) *puOptions = cacheSigning.uCachedOptions; bAskUser = FALSE; } } } // otherwise, get phrase from user if (bAskUser) { sEmptyCache (&cacheSigning); // call PGPcl routine to post passphrase dialog err = PGPclGetPhrase (context, keysetSigning, hwnd, szPrompt, &cacheSigning.pszCachedPassphrase, NULL, NULL, 0, pkeySigning, puOptions, uFlags, &cacheSigning.pCachedPasskey, &cacheSigning.iCachedPasskeyLength, 0, 0, tlsContext, pkeysetAdded,szTitle); // user entered phrase -- setup cache if ((err == kPGPError_NoErr) && (cacheSigning.pszCachedPassphrase || cacheSigning.pCachedPasskey)) { // scramble cache contents sScrambleCache (&cacheSigning); if (bCacheEnabled) { sSetCacheDuration (&cacheSigning, uCacheSecs); if (!cacheSigning.bCacheActive) { cacheSigning.bCacheActive = TRUE; _beginthreadex (NULL, 0, (LPTHREAD_START_ROUTINE)sClearSigningCacheThread, 0, 0, &dw); } } // copy to caller's buffers err = sCopyCache (&cacheSigning, context, pszBuffer, ppPasskeyBuffer, piPasskeyLength); PGPGetHashAlgUsed (*pkeySigning, &cacheSigning.CachedHashAlg); if (pulHashAlg) *pulHashAlg = cacheSigning.CachedHashAlg; if (bCacheEnabled) { if (puOptions) cacheSigning.uCachedOptions = *puOptions; else cacheSigning.uCachedOptions = 0; PGPGetKeyIDFromKey (*pkeySigning, &keyid); PGPExportKeyID (&keyid, cacheSigning.CachedKeyID, &size); PGPGetKeyNumber (*pkeySigning, kPGPKeyPropAlgID, &cacheSigning.CachedKeyAlg); } else { sEmptyCache (&cacheSigning); } } // problem (cancel or other error) -- flush cache else { sEmptyCache (&cacheSigning); sSetCacheDuration (&cacheSigning, 0); if (err == kPGPError_NoErr) err = kPGPError_UserAbort; } } LeaveCriticalSection (&criticalSectionCache); return err; }
PGPError addToWorkingRingSet(struct pgpmainBones *mainbPtr, PGPKeySetRef keySet, PGPBoolean bAddToDefault ) { PGPContextRef context = mainbPtr->pgpContext; PGPEnv *env = pgpContextGetEnvironment( context ); struct pgpfileBones *filebPtr = mainbPtr->filebPtr; struct pgpenvBones *envbPtr = mainbPtr->envbPtr; PGPKeyIterRef iter = NULL; PGPError err; PGPKeyRef key = 0; PGPKeyRef origkey = 0; PGPKeyID keyid; int copying = 0; int newkeys = 0, newsigs = 0, newuids = 0, newrvks = 0; PGPKeyListRef keylist = 0; char* ringfile = ""; PGPInt32 pri; PGPInt32 verbose = pgpenvGetInt( env, PGPENV_VERBOSE, &pri, &err ); PGPInt32 interactive = envbPtr->interactiveAdd; PGPBoolean batchmode = pgpenvGetInt( env, PGPENV_BATCHMODE, &pri, &err ); PGPKeySetRef keepset = NULL, origset = NULL; PGPBoolean ans; PGPKeySetRef defKeySet = kPGPInvalidRef; err = PGPOpenDefaultKeyRings(context, kPGPKeyRingOpenFlags_Mutable, &defKeySet); if(IsPGPError(err)) goto done; if(bAddToDefault) mainbPtr->workingRingSet = defKeySet; pgpAssertAddrValid( mainbPtr, struct pgpmainBones ); pgpAssertAddrValid( mainbPtr->workingRingSet, PGPKeySetRef ); err = PGPNewEmptyKeySet( mainbPtr->workingRingSet, &origset ); pgpAssertNoErr(err); err = PGPOrderKeySet( keySet, kPGPAnyOrdering, &keylist ); pgpAssertNoErr(err); err = PGPNewKeyIter( keylist, &iter ); pgpAssertNoErr(err); if(verbose) fprintf(filebPtr->pgpout, LANG("\nPASS 1.. find the existing keys\n")); err = PGPKeyIterRewind( iter ); pgpAssertNoErr(err); err = PGPKeyIterNext( iter, &key); if( err ) { fprintf( filebPtr->pgpout,LANG("Could not read key from keyfile.")); goto done; } while( key ) { err = PGPGetKeyIDFromKey( key, &keyid ); pgpAssertNoErr(err); err = PGPGetKeyByKeyID( defKeySet, &keyid, kPGPPublicKeyAlgorithm_Invalid, &origkey ); if(err == 0 ) err = pgpAddKeyToKeySet( origkey, origset ); err = PGPKeyIterNext( iter, &key ); } if(verbose) fprintf(filebPtr->pgpout, LANG("\nPASS 2.. ask whether to add the new keys\n")); err = PGPKeyIterRewind( iter ); pgpAssertNoErr(err); err = PGPKeyIterNext( iter, &key); if( err ) { fprintf( filebPtr->pgpout,LANG("Could not read key from keyfile.")); goto done; } while( key ) { PGPBoolean isnew; err = PGPGetKeyIDFromKey( key, &keyid ); pgpAssertNoErr(err); err = PGPGetKeyByKeyID( defKeySet, &keyid, kPGPPublicKeyAlgorithm_Invalid, &origkey ); /* Copy if all criteria are met */ copying = 0; isnew = FALSE; if(err == 0 ) { copying = 1; } else { /* is a new key*/ err = pgpShowKeyListFormat( filebPtr, mainbPtr->workingRingSet, iter, key, kShow_Sigs | kShow_Checks ); if( interactive ) { fprintf( filebPtr->pgpout, LANG( "\nDo you want to add this key to keyring '%s' (y/N)? "), ringfile); copying = getyesno(filebPtr,'n', batchmode ) ? 1 : 0; } else copying = 1; if(copying) { isnew=TRUE; newkeys++; } } if( copying ) { if(keepset == NULL) { err = PGPNewKeySet( context, &keepset ); pgpAssertNoErr(err); } err = pgpAddKeyToKeySet( key, keepset ); if(IsPGPError(err)) { pgpShowError(filebPtr, err,__FILE__,__LINE__); } if( isnew && !batchmode ) { /* This is not efficient, because it loops on keepset, so avoid calling it in batchmode. */ err = pgpMarkKeyInSet( keepset, key ); } } err = PGPKeyIterNext( iter, &key ); if( err != 0 || key == 0 ) { break; } } if(err == kPGPError_EndOfIteration) err = 0; if( newkeys > 0 && !interactive ) { fprintf( filebPtr->pgpout, LANG("\nkeyfile contains %d new keys. "), newkeys); fprintf( filebPtr->pgpout, LANG( "Add these keys to keyring ? (Y/n) ")); fflush( filebPtr->pgpout ); ans = getyesno(filebPtr, 'y', batchmode); /* add a newline to make it easier to read */ fprintf(filebPtr->pgpout, "\n"); fflush(filebPtr->pgpout); if(!ans) goto done; } if(verbose) fprintf(filebPtr->pgpout, LANG( "\nPASS 3.. show the new userids and new sigs\n")); { PGPSize keys,uids,sigs,rvks; err = pgpMarkKeySet( origset ); pgpAssertNoErr(err); err = PGPAddKeys( origset, keepset ); pgpAssertNoErr(err); /* * mark default key set to determine which keys are * being added in, need to do this because mainbPtr->workingRingSet * might be a in memory key set */ err = pgpMarkKeySet( defKeySet ); pgpAssertNoErr(err); err = PGPAddKeys( keepset, defKeySet ); pgpAssertNoErr(err); err = pgpShowKeySetUnmarked( filebPtr, defKeySet, &keys, &uids, &sigs, &rvks ); pgpAssertNoErr(err); /*newkeys += keys;*/ newuids += uids; newsigs += sigs; newrvks += rvks; } if(verbose) fprintf(filebPtr->pgpout, LANG("\nPASS 4... add them to the keyring\n")); if(!bAddToDefault) { err = PGPAddKeys( keepset, mainbPtr->workingRingSet ); pgpAssertNoErr(err); } /* For now AddKeys should be more or less the same as mergekeys */ /* User feedback */ if( newsigs == 0 && newkeys == 0 && newuids == 0 && newrvks == 0 ) { goto done; } /* Check signatures */ PGPCheckKeyRingSigs( keepset, mainbPtr->workingRingSet, 0, NULL, NULL ); if( err ) { if( verbose ) { fprintf(filebPtr->pgpout, LANG( "addToWorkingRingSet: pgpDoCheckKeySet() returned %d\n"), err); } goto done; } /* More user feedback */ fprintf(filebPtr->pgpout, LANG("\nKeyfile contains:\n")); if (newkeys) fprintf(filebPtr->pgpout, LANG("%4d new key(s)\n"), newkeys); if (newsigs) fprintf(filebPtr->pgpout, LANG("%4d new signatures(s)\n"), newsigs); if (newuids) fprintf(filebPtr->pgpout, LANG("%4d new user ID(s)\n"), newuids); if (newrvks) fprintf(filebPtr->pgpout, LANG("%4d new revocation(s)\n"), newrvks); err = PGPPropagateTrust( mainbPtr->workingRingSet ); pgpAssertNoErr(err); /* mainbPtr->workingRingSet = ringSet;*/ /* mainbPtr->workingGroupSet = NULL;*/ err = pgpProcessUncertifiedKeys( mainbPtr, keepset ); if( IsPGPError(err)) { if(err == kPGPError_UserAbort) err = kPGPError_NoErr; goto done; } err = pgpProcessUntrustedKeys( mainbPtr, keepset, mainbPtr->workingRingSet ); done: if(PGPKeySetNeedsCommit(mainbPtr->workingRingSet)) PGPCommitKeyRingChanges(mainbPtr->workingRingSet); if(defKeySet != kPGPInvalidRef) PGPFreeKeySet(defKeySet); if(keepset != NULL) PGPFreeKeySet( keepset ); if( iter ) PGPFreeKeyIter( iter ); if( keylist) PGPFreeKeyList( keylist ); if( origset ) PGPFreeKeySet( origset ); /* The event handler will call addToRingSetFinish( ringSet ); before this is done */ return err; }
/* Examines the keys in keyset and updates the trust of corresponding keys in ringSet. It is not assumed that parameter keyset comes from the same key database as ringSet. */ PGPError pgpProcessUntrustedKeys( struct pgpmainBones *mainbPtr, PGPKeySetRef keyset, PGPKeySetRef ringSet ) { struct pgpfileBones *filebPtr = mainbPtr->filebPtr; PGPKeyRef key,origkey; PGPKeyID keyid; PGPKeyIterRef keyiter = NULL; PGPKeyListRef keylist = NULL; PGPError err; err = PGPOrderKeySet( keyset, kPGPAnyOrdering, &keylist); pgpAssertNoErr(err); err = PGPNewKeyIter( keylist, &keyiter ); pgpAssertNoErr(err); for(;;) { PGPBoolean endloop; /* loop while there are any (at least marginally valid) keys whose trust has not been set. */ /* while keys still with undefined trust, allow wetware editing of trust parameter (avoid iterating main ringSet due to ldap servers and potential size of set) */ endloop = TRUE; err = PGPKeyIterRewind( keyiter ); pgpAssertNoErr(err); err = PGPKeyIterNext( keyiter, &key); while( key ) { PGPInt32 validity; PGPUserValue val; err = PGPGetKeyIDFromKey( key, &keyid ); if( err ) { pgpShowError( filebPtr, err,__FILE__,__LINE__ ); goto next; } err = PGPGetKeyByKeyID( ringSet, &keyid, kPGPPublicKeyAlgorithm_Invalid, &origkey ); if( err ) { pgpShowError( filebPtr, err,__FILE__,__LINE__ ); goto next; } err = PGPGetKeyNumber( key, kPGPKeyPropValidity, &validity); pgpAssertNoErr(err); err = PGPGetKeyUserVal( key, &val ); pgpAssertNoErr(err); if( (validity > kPGPValidity_Invalid) && ! ((PGPInt32)val & kMark_Trust ) ) /* key has not been processed*/ { PGPUserIDRef userid; PGPSize scrap; char useridstr[ kPGPMaxUserIDSize ]; err = PGPGetPrimaryUserID( origkey, &userid ); pgpAssertNoErr(err); err = PGPGetUserIDStringBuffer( userid, kPGPUserIDPropName, kPGPMaxUserIDSize, useridstr, &scrap); pgpAssertNoErr(err); if( pgpGetKeyTrust( origkey ) <= kPGPKeyTrust_Unknown ) { err = pgpShowKeyBrief( filebPtr, key ); pgpAssertNoErr(err); err = pgpEditPublicTrustParameter( filebPtr, useridstr, key ); if( err ) { pgpShowError( filebPtr, err,__FILE__,__LINE__ ); goto done; } PGPPropagateTrust( ringSet ); PGPSetKeyUserVal( key, (PGPUserValue)( (PGPInt32)val | kMark_Trust )); /* key has been processed*/ endloop = FALSE; } } next: err = PGPKeyIterNext( keyiter, &key ); /*if err, no more*/ } if( endloop == TRUE ) break; } done: if( keyiter ) PGPFreeKeyIter( keyiter ); if( keylist ) PGPFreeKeyList( keylist ); return err; }
PGPError pgpProcessUncertifiedKeys( struct pgpmainBones *mainbPtr, PGPKeySetRef keyset ) { struct pgpfileBones *filebPtr = mainbPtr->filebPtr; PGPKeyRef key,origkey; PGPKeyID keyid; PGPKeyIterRef keyiter = NULL; PGPKeyListRef keylist = NULL; PGPError err; PGPBoolean ask_first_latch = TRUE; pgpAssertAddrValid( mainbPtr, struct pgpmainBones ); pgpAssertAddrValid( mainbPtr->workingRingSet, PGPKeySetRef ); err = PGPOrderKeySet( keyset, kPGPAnyOrdering, &keylist); pgpAssertNoErr(err); err = PGPNewKeyIter( keylist, &keyiter ); pgpAssertNoErr(err); /* Sign unverifiable keys by hand */ err = PGPKeyIterRewind( keyiter ); pgpAssertNoErr(err); err = PGPKeyIterNext( keyiter, &key); pgpAssertNoErr(err); while( key ) { PGPBoolean issec; PGPGetKeyBoolean( key, kPGPKeyPropIsSecret, &issec ); if(issec) goto next; err = PGPGetKeyIDFromKey( key, &keyid ); if( IsPGPError(err) ) { pgpShowError( filebPtr, err,__FILE__,__LINE__ ); goto next; } err = PGPGetKeyByKeyID( mainbPtr->workingRingSet, &keyid, kPGPPublicKeyAlgorithm_Invalid, &origkey ); if( IsPGPError(err) ) { if( err != kPGPError_ItemNotFound ) pgpShowError( filebPtr, err,__FILE__,__LINE__ ); goto next; } /*mainbPtr->workingRingSet=ringSet;*/ /*mainbPtr->workingGroupSet=NULL;*/ err=askToSign( mainbPtr, origkey, ask_first_latch ); switch(err) { case kPGPError_NoErr: break; case kPGPError_UserAbort: /*err = kPGPError_NoErr;*/ goto done; case kPGPError_ItemAlreadyExists: goto next; default: pgpShowError( filebPtr, err,__FILE__,__LINE__ ); goto done; } ask_first_latch = FALSE; /* should stay false now */ next: err = PGPKeyIterNext( keyiter, &key ); /*if err, there are no more*/ } if( err == kPGPError_EndOfIteration ) err = kPGPError_NoErr; done: if( keyiter ) PGPFreeKeyIter( keyiter ); if( keylist ) PGPFreeKeyList( keylist ); return err; }
PGPError KeyIdFilterFromKeySet( PGPKeySetRef keySet, PGPFilterRef* filter) { PGPError error = kPGPError_NoErr; PGPKeyListRef list = kPGPInvalidRef; PGPKeyIterRef iter = kPGPInvalidRef; PGPKeyRef key = kPGPInvalidRef; PGPFilterRef aFilter = kPGPInvalidRef; PGPFilterRef idFilter= kPGPInvalidRef; PGPKeyID keyId; error = PGPOrderKeySet( keySet, kPGPAnyOrdering, &list); if( IsntPGPError(error) ) { error = PGPNewKeyIter( list, &iter); if(IsntPGPError(error) ) { PGPError iterError = kPGPError_NoErr; do { iterError = PGPKeyIterNext(iter, &key); if( IsntPGPError(iterError) ) { error = PGPGetKeyIDFromKey( key, &keyId); if( IsntPGPError(error) ) { error = PGPNewSigKeyIDFilter( g_Context, &keyId, &aFilter ); if(idFilter == kPGPInvalidRef) { idFilter = aFilter; } else { PGPFilterRef combinedFilter = NULL; error = PGPUnionFilters(idFilter, aFilter, &combinedFilter); idFilter = combinedFilter; } } } }while(IsntPGPError(iterError) && IsntPGPError(error)); PGPFreeKeyIter(iter); } PGPFreeKeyList(list); } if( IsntPGPError(error) ) { *filter = idFilter; } return error; }