/* mark an existing keySet before merging in a new keySet, so we can determine new userids, sigs / revocations */ PGPError pgpMarkKeySet( PGPKeySetRef keySet ) { PGPError err,er2; PGPKeyRef key; PGPKeyListRef keylist; PGPKeyIterRef iter; err = PGPOrderKeySet( keySet, kPGPAnyOrdering, &keylist ); pgpAssertNoErr(err); err = PGPNewKeyIter( keylist, &iter ); pgpAssertNoErr(err); err = PGPKeyIterRewind( iter ); pgpAssertNoErr(err); PGPKeyIterNext( iter, &key); /*if err, there are none.*/ while( key ) { err = pgpMarkKey( iter, key ); if(err) break; PGPKeyIterNext( iter, &key); /*if err, there are no more.*/ } er2 = PGPFreeKeyIter( iter ); pgpAssertNoErr(err); er2 = PGPFreeKeyList( keylist ); pgpAssertNoErr(err); 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 */
PGPError pgpShowKeySetMarked( struct pgpfileBones *filebPtr, PGPKeySetRef keySet, PGPSize *newKeyCount, PGPSize *newUIDCount, PGPSize *newSigCount, PGPSize *newRevokeCount ) { PGPError err; PGPKeyRef key; PGPKeyListRef keylist = NULL; PGPKeyIterRef keyiter = NULL; *newKeyCount = 0; *newUIDCount = 0; *newSigCount = 0; *newRevokeCount = 0; err = PGPOrderKeySet( keySet, kPGPAnyOrdering, &keylist ); pgpAssertNoErr(err); err = PGPNewKeyIter( keylist, &keyiter ); pgpAssertNoErr(err); err = PGPKeyIterRewind( keyiter ); pgpAssertNoErr(err); PGPKeyIterNext( keyiter, &key); /*if err, there are none.*/ while( key ) { PGPSize keyc, uidc, sigc, rvkc; err = pgpShowKeyMarked( filebPtr, keyiter, key, &keyc, &uidc, &sigc, &rvkc ); (*newKeyCount) += uidc; (*newUIDCount) += uidc; (*newSigCount) += sigc; (*newRevokeCount) += rvkc; if(err) break; PGPKeyIterNext( keyiter, &key); /*if err, there are no more.*/ } if( keyiter ) PGPFreeKeyIter( keyiter ); if( keylist ) PGPFreeKeyList( keylist ); pgpAssertNoErr(err); return err; }
static PGPError sRevokeKeySplit ( PGPContextRef context, PGPKeySetRef keyset, PGPKeyRef key, PGPByte* passkey, PGPSize sizePasskey) { UINT u; PGPKeyListRef keylist; PGPKeyIterRef keyiter; PGPSubKeyRef subkey; PGPError err; err = PGPRevokeKey (key, PGPOPasskeyBuffer (context, passkey, sizePasskey), PGPOLastOption (context)); if (IsPGPError (err)) return err; PGPGetKeyNumber (key, kPGPKeyPropAlgID, &u); switch (u) { case kPGPPublicKeyAlgorithm_RSA : break; case kPGPPublicKeyAlgorithm_DSA : PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist); PGPNewKeyIter (keylist, &keyiter); PGPKeyIterSeek (keyiter, key); PGPKeyIterNextSubKey (keyiter, &subkey); while (subkey) { err = PGPRevokeSubKey (subkey, PGPOPasskeyBuffer (context, passkey, sizePasskey), PGPOLastOption (context)); PGPKeyIterNextSubKey (keyiter, &subkey); } PGPFreeKeyIter (keyiter); PGPFreeKeyList (keylist); break; default : break; } return err; }
PGPBoolean InitSigningKeyComboBox (CPGPKeySetPassphraseDialogOptions *options) { PGPKeyListRef KeyList; PGPKeyIterRef KeyIter; PGPKeyRef Key; PGPBoolean bSecret, bRevoked, bExpired, bCanSign; PGPBoolean bAtLeastOneSecretKey; char szNameFinal[kPGPMaxUserIDSize]; PGPOrderKeySet (options->mKeySet, kPGPValidityOrdering, &KeyList); PGPNewKeyIter (KeyList, &KeyIter); bAtLeastOneSecretKey = FALSE; PGPKeyIterNext (KeyIter, &Key); while (Key) { PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret); if (bSecret) { PGPGetKeyBoolean (Key, kPGPKeyPropIsRevoked, (unsigned char *)&bRevoked); PGPGetKeyBoolean (Key, kPGPKeyPropIsExpired, (unsigned char *)&bExpired); PGPGetKeyBoolean (Key, kPGPKeyPropCanSign, (unsigned char *)&bCanSign); if (!bRevoked && !bExpired && bCanSign) { bAtLeastOneSecretKey = TRUE; GetKeyString(Key,szNameFinal); fprintf(stdout, "\n%s\n", szNameFinal); } } PGPKeyIterNext (KeyIter, &Key); } PGPFreeKeyIter (KeyIter); PGPFreeKeyList (KeyList); return (bAtLeastOneSecretKey); }
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 */
static PGPError sChangeKeyPhrase ( PGPContextRef context, PGPKeySetRef keyset, PGPKeyRef key, LPSTR szOld, PGPByte* pPasskeyOld, PGPSize sizePasskeyOld, PGPByte* pPasskey, PGPSize sizePasskey) { UINT u; PGPKeyListRef keylist; PGPKeyIterRef keyiter; PGPSubKeyRef subkey; PGPError err; if (szOld) { err = PGPChangePassphrase (key, PGPOPassphrase (context, szOld), PGPOPasskeyBuffer (context, pPasskey, sizePasskey), PGPOLastOption (context)); } else if (sizePasskeyOld > 0) { err = PGPChangePassphrase (key, PGPOPasskeyBuffer (context, pPasskeyOld, sizePasskeyOld), PGPOPasskeyBuffer (context, pPasskey, sizePasskey), PGPOLastOption (context)); } else { err = PGPChangePassphrase (key, PGPOPassphrase (context, ""), PGPOPasskeyBuffer (context, pPasskey, sizePasskey), PGPOLastOption (context)); } if (IsPGPError (err)) return err; PGPGetKeyNumber (key, kPGPKeyPropAlgID, &u); switch (u) { case kPGPPublicKeyAlgorithm_RSA : break; case kPGPPublicKeyAlgorithm_DSA : PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist); PGPNewKeyIter (keylist, &keyiter); PGPKeyIterSeek (keyiter, key); PGPKeyIterNextSubKey (keyiter, &subkey); while (subkey) { if (szOld) { err = PGPChangeSubKeyPassphrase (subkey, PGPOPassphrase (context, szOld), PGPOPasskeyBuffer (context, pPasskey, sizePasskey), PGPOLastOption (context)); } else if (sizePasskeyOld > 0) { err = PGPChangeSubKeyPassphrase (subkey, PGPOPasskeyBuffer (context, pPasskeyOld, sizePasskeyOld), PGPOPasskeyBuffer (context, pPasskey, sizePasskey), PGPOLastOption (context)); } else { err = PGPChangeSubKeyPassphrase (subkey, PGPOPassphrase (context, ""), PGPOPasskeyBuffer (context, pPasskey, sizePasskey), PGPOLastOption (context)); } PGPKeyIterNextSubKey (keyiter, &subkey); } PGPFreeKeyIter (keyiter); PGPFreeKeyList (keylist); break; default : break; } return err; }
// Signer combo box PGPError pgpSigningPassphraseCL( PGPContextRef context, CPGPSigningPassphraseDialogOptions *options) { PGPError err = 0; GPP gpp; memset(&gpp,0x00,sizeof(GPP)); gpp.context=context; gpp.options=options; /* * XXX * Currently expects to display only *ONE* key. * The caller must set the keyset in the options to consist * of the signing key that the caller wants this routine * to verify */ // Initialize stuff if (!InitSigningKeyComboBox (options)) { return kPGPError_UserAbort; // kPGPError_Win32_NoSecret_Key } if (options->mPrompt) puts(options->mPrompt); else printf("Need a pass phrase to use this key\n"); // Need to ask and get Passphrase PGPKeyListRef KeyList; PGPKeyIterRef KeyIter; PGPKeyRef key; PGPOrderKeySet (options->mKeySet,kPGPValidityOrdering,&KeyList); PGPNewKeyIter (KeyList, &KeyIter); PGPKeyIterNext (KeyIter, &key); while (1) { FreePassphrases(&gpp); gpp.pszPassPhrase = (char *)secAlloc (gpp.context, KEYSIZE); if (gpp.pszPassPhrase) { PGPBoolean bShared; PGPInt32 len = pgpCLGetPass(stdout, gpp.pszPassPhrase, KEYSIZE); if (len < 0) { err = kPGPError_UserAbort; break; } *(options->mPassphrasePtr) = gpp.pszPassPhrase; // Check Shared status err = PGPGetKeyBoolean(key, kPGPKeyPropIsSecretShared, &bShared); if (IsntPGPError(err) && bShared) { // So, they want to do a shared key *(options->mPassphraseKeyPtr) = key; err = kPGPError_KeyUnusableForSignature; break; } if (PassphraseLengthAndQualityOK(options,gpp.pszPassPhrase)) { if (!options->mVerifyPassphrase) { err = kPGPError_NoErr; break; } err = ValidateSigningPhrase(&gpp,gpp.pszPassPhrase,key); if (IsntPGPError(err)) { err = kPGPError_NoErr; break; } } else { ClearPassphrases(&gpp); FreePassphrases(&gpp); break; } } else { err = kPGPError_OutOfMemory; break; } } PGPFreeKeyIter(KeyIter); PGPFreeKeyList(KeyList); ClearPassphrases(&gpp); if (err != kPGPError_NoErr) FreePassphrases(&gpp); return(err); }
PGPError pgpUserChooseAndDisableKeys( struct pgpmainBones *mainbPtr, PGPKeySetRef keysToDisable ) { struct pgpfileBones *filebPtr = mainbPtr->filebPtr; PGPError err; PGPKeyListRef keylist; PGPKeyIterRef keyiter; PGPKeyRef key; err = PGPOrderKeySet( keysToDisable, kPGPAnyOrdering, &keylist ); pgpAssertNoErr(err); err = PGPNewKeyIter( keylist, &keyiter ); pgpAssertNoErr(err); err = PGPKeyIterRewind( keyiter ); pgpAssertNoErr(err); err = PGPKeyIterNext( keyiter, &key ); while( key != NULL ) { PGPBoolean propData = FALSE; pgpShowKeyBrief( filebPtr, key ); err = PGPGetKeyBoolean( key, kPGPKeyPropIsDisabled, &propData ); pgpAssertNoErr( err ); if( propData ) { fprintf( filebPtr->pgpout, LANG("\nKey is already disabled.\n" "Do you want to enable this key again (y/N)? ")); if( getyesno( filebPtr,'n',0) ) { if( mainbPtr->workingKeyServer ) { PGPKeySetRef single,failed=NULL; err = PGPNewSingletonKeySet( key, &single ); pgpAssertNoErr(err); /* does it get re-enabled??*/ err = PGPDisableFromKeyServer( mainbPtr->workingKeyServer, single, &failed ); if( IsPGPError(err) ) { pgpShowError( filebPtr, err, 0,0); if( failed ) PGPFreeKeySet(failed); } PGPFreeKeySet( single ); } else { err = PGPEnableKey( key ); pgpAssertNoErr( err ); } } } else { fprintf( filebPtr->pgpout, LANG("\nDisable this key (y/N)? ")); if( getyesno( filebPtr,'n',0) ) { if( mainbPtr->workingKeyServer ) { PGPKeySetRef single,failed=NULL; err = PGPNewSingletonKeySet( key, &single ); pgpAssertNoErr(err); err = PGPDisableFromKeyServer( mainbPtr->workingKeyServer, single, &failed ); if( IsPGPError(err) ) { pgpShowError( filebPtr, err, 0,0); if( failed ) PGPFreeKeySet(failed); } PGPFreeKeySet( single ); } else { err = PGPDisableKey( key ); pgpAssertNoErr( err ); } } } err = PGPKeyIterNext( keyiter, &key ); } if( err == kPGPError_EndOfIteration ) err = kPGPError_NoErr; return err; }
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 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 PGPclExport PGPclSendKeysToServer ( PGPContextRef context, PGPtlsContextRef tlsContext, HWND hwndParent, UINT uServer, PGPKeyServerEntry* pkeyserver, PGPKeySetRef keysetMain, PGPKeySetRef keysetToSend) { PGPError err = kPGPError_NoErr; PGPKeySetRef keyset = kInvalidPGPKeySetRef; PGPKeyListRef keylist = kInvalidPGPKeyListRef; PGPKeyIterRef keyiter = kInvalidPGPKeyIterRef; PGPValidatePtr (keysetToSend); PGPValidatePtr (context); PGPValidatePtr (pkeyserver); // derive server from userid if (uServer == PGPCL_USERIDBASEDSERVER) { PGPKeyRef key = kInvalidPGPKeyRef; CHAR szUserID[kPGPMaxUserIDSize+1]; PGPSize size; err = PGPOrderKeySet (keysetToSend, kPGPAnyOrdering, &keylist); CKERR; err = PGPNewKeyIter (keylist, &keyiter); CKERR; while ( IsntPGPError (PGPKeyIterNext (keyiter, &key)) && PGPKeyRefIsValid (key)) { err = PGPNewSingletonKeySet (key, &keyset); CKERR; err = PGPGetPrimaryUserIDNameBuffer (key, kPGPMaxUserIDSize, szUserID, &size); CKERR; err = sSendToServerInternal (hwndParent, context, tlsContext, uServer, pkeyserver, szUserID, keysetMain, keyset); CKERR; } } // use indicated or caller-supplied server else { err = sSendToServerInternal (hwndParent, context, tlsContext, uServer, pkeyserver, "", keysetMain, keysetToSend); } done : if (PGPKeyListRefIsValid (keylist)) PGPFreeKeyList (keylist); if (PGPKeyIterRefIsValid (keyiter)) PGPFreeKeyIter (keyiter); if (PGPKeySetRefIsValid (keyset)) PGPFreeKeySet (keyset); return err; }
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 PGPX509CertFromExport( PGPContextRef context, PGPUInt32 uX509Alg, PGPByte* expkeyidX509, PGPByte* pIASNX509, PGPUInt32 uX509IASNLength, PGPKeySetRef keyset, PGPKeyRef* pkeyX509, PGPSigRef* psigX509 ) { PGPKeyListRef keylist = kInvalidPGPKeyListRef; PGPKeyIterRef keyiter = kInvalidPGPKeyIterRef; PGPKeySetRef keysetX509 = kInvalidPGPKeySetRef; PGPKeyRef key = kInvalidPGPKeyRef; PGPUserIDRef userid = kInvalidPGPUserIDRef; PGPSigRef sig = kInvalidPGPSigRef; PGPError err = kPGPError_NoErr; PGPByte* pIASN = NULL; PGPKeyID keyid; PGPSize size; PGPValidatePtr (pkeyX509); PGPValidatePtr (psigX509); *pkeyX509 = kInvalidPGPKeyRef; *psigX509 = kInvalidPGPSigRef; // get X.509 key if ((pIASNX509 != NULL) && (uX509Alg != kPGPPublicKeyAlgorithm_Invalid)) { err = PGPImportKeyID (expkeyidX509, &keyid); CKERR; err = PGPGetKeyByKeyID ( keyset, &keyid, (PGPPublicKeyAlgorithm)uX509Alg, pkeyX509); CKERR; } // get X.509 sig if (PGPKeyRefIsValid (*pkeyX509)) { err = PGPNewSingletonKeySet (*pkeyX509, &keysetX509); CKERR; err = PGPOrderKeySet (keysetX509, kPGPAnyOrdering, &keylist); CKERR; err = PGPNewKeyIter (keylist, &keyiter); CKERR; err = PGPKeyIterNext (keyiter, &key); CKERR; err = PGPKeyIterNextUserID (keyiter, &userid); CKERR; while (userid) { PGPKeyIterNextUIDSig (keyiter, &sig); while ( (sig != kInvalidPGPSigRef) && (*psigX509 == kInvalidPGPSigRef)) { size = 0; PGPGetSigPropertyBuffer (sig, kPGPSigPropX509IASN, 0, NULL, &size); if (size == uX509IASNLength) { pIASN = (PGPByte *)PGPNewData ( PGPGetContextMemoryMgr (context), size, kPGPMemoryMgrFlags_Clear); if (pIASN) { err = PGPGetSigPropertyBuffer (sig, kPGPSigPropX509IASN, size, pIASN, &size); CKERR; if (pgpMemoryEqual (pIASN, pIASNX509, size)) { *psigX509 = sig; } PGPFreeData (pIASN); pIASN = NULL; } } PGPKeyIterNextUIDSig (keyiter, &sig); } PGPKeyIterNextUserID (keyiter, &userid); } } done : if (pIASN != NULL) PGPFreeData (pIASN); if (PGPKeySetRefIsValid (keysetX509)) PGPFreeKeySet (keysetX509); if (PGPKeyIterRefIsValid (keyiter)) PGPFreeKeyIter (keyiter); if (PGPKeyListRefIsValid (keylist)) PGPFreeKeyList (keylist); return err; }
BOOL AddKeySetToRecipientsTable (HWND hDlg, PGPKeySetRef KeySet, CPGPDecryptionPassphraseDialogOptions *options) { BOOL bAtLeastOneValidSecretKey = FALSE; UINT uUnknownKeys = 0; PGPKeyListRef KeyList; PGPKeyIterRef KeyIter; PGPKeyRef Key; PGPSubKeyRef SubKey; UINT u, uIndex, uKeyBits, uAlgorithm; INT iKeyDefault, iKeySelected; PGPBoolean bSecret, bCanDecrypt; CHAR szName[kPGPMaxUserIDSize]; CHAR sz[128]; PGPOrderKeySet (KeySet, kPGPValidityOrdering, &KeyList); PGPNewKeyIter (KeyList, &KeyIter); iKeySelected = -1; iKeyDefault = -1; PGPKeyIterNext (KeyIter, &Key); while (Key) { PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret); PGPGetKeyBoolean (Key, kPGPKeyPropCanDecrypt, &bCanDecrypt); PGPGetKeyNumber (Key, kPGPKeyPropAlgID, (int *)&uAlgorithm); if (bSecret && bCanDecrypt) bAtLeastOneValidSecretKey = TRUE; // get name on key PGPGetPrimaryUserIDNameBuffer (Key, sizeof(szName), szName, &u); if (u > MAXDECRYPTIONNAMECHAR) { u = MAXDECRYPTIONNAMECHAR; lstrcat (szName, "..."); } else szName[u] = '\0'; // append key type / size info to name lstrcat (szName, " ("); switch (uAlgorithm) { case kPGPPublicKeyAlgorithm_RSA : LoadString (gPGPsdkUILibInst, IDS_RSA, sz, sizeof(sz)); lstrcat (szName, sz); lstrcat (szName, "/"); PGPGetKeyNumber (Key, kPGPKeyPropBits, (int *)&uKeyBits); wsprintf (sz, "%i", uKeyBits); lstrcat (szName, sz); break; case kPGPPublicKeyAlgorithm_DSA : LoadString (gPGPsdkUILibInst, IDS_DH, sz, sizeof(sz)); lstrcat (szName, sz); lstrcat (szName, "/"); PGPKeyIterNextSubKey (KeyIter, &SubKey); if (SubKey) { PGPGetSubKeyNumber (SubKey, kPGPKeyPropBits, (int *)&uKeyBits); wsprintf (sz, "%i", uKeyBits); lstrcat (szName, sz); } else lstrcat (szName, "???"); break; default : LoadString (gPGPsdkUILibInst, IDS_UNKNOWN, sz, sizeof(sz)); lstrcat (szName, sz); lstrcat (szName, "/"); lstrcat (szName, sz); break; } lstrcat (szName, ")"); uIndex = SendDlgItemMessage (hDlg, IDC_KEYLISTBOX, LB_ADDSTRING, 0, (LPARAM)szName); PGPKeyIterNext (KeyIter, &Key); } PGPFreeKeyIter (KeyIter); PGPFreeKeyList (KeyList); return bAtLeastOneValidSecretKey; }
BOOL InitSigningKeyComboBox (HWND hDlg, CPGPKeySetPassphraseDialogOptions *options) { PGPKeyListRef KeyList; PGPKeyIterRef KeyIter; PGPKeyRef Key; PGPKeyRef KeyDefault; UINT uIndex; INT iKeyDefault, iKeySelected; PGPBoolean bSecret, bRevoked, bExpired, bCanSign; BOOL bAtLeastOneSecretKey; CHAR szNameFinal[kPGPMaxUserIDSize]; HDC hdc; RECT rc; INT iComboWidth; HFONT hFont; PGPOrderKeySet (options->mKeySet, kPGPValidityOrdering, &KeyList); PGPNewKeyIter (KeyList, &KeyIter); PGPGetDefaultPrivateKey (options->mKeySet, &KeyDefault); SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc); iComboWidth = rc.right-rc.left - GetSystemMetrics (SM_CXVSCROLL); hdc = GetDC (GetDlgItem (hDlg, IDC_SIGNKEYCOMBO)); hFont = (HFONT)GetStockObject (DEFAULT_GUI_FONT); SelectObject (hdc, hFont); iKeySelected = -1; iKeyDefault = 0; bAtLeastOneSecretKey = FALSE; PGPKeyIterNext (KeyIter, &Key); while (Key) { PGPGetKeyBoolean (Key, kPGPKeyPropIsSecret, &bSecret); if (bSecret) { PGPGetKeyBoolean (Key, kPGPKeyPropIsRevoked, (unsigned char *)&bRevoked); PGPGetKeyBoolean (Key, kPGPKeyPropIsExpired, (unsigned char *)&bExpired); PGPGetKeyBoolean (Key, kPGPKeyPropCanSign, (unsigned char *)&bCanSign); if (!bRevoked && !bExpired && bCanSign) { bAtLeastOneSecretKey = TRUE; GetKeyString(hdc,iComboWidth,Key,szNameFinal); uIndex = SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO, CB_ADDSTRING, 0, (LPARAM)szNameFinal); if (uIndex != CB_ERR) { SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO, CB_SETITEMDATA, uIndex, (LPARAM)Key); if (options->mDefaultKey) { if (Key == options->mDefaultKey) iKeySelected = uIndex; } if (Key == KeyDefault) iKeyDefault = uIndex; } } } PGPKeyIterNext (KeyIter, &Key); } PGPFreeKeyIter (KeyIter); PGPFreeKeyList (KeyList); if (iKeySelected == -1) iKeySelected = iKeyDefault; SendDlgItemMessage (hDlg, IDC_SIGNKEYCOMBO, CB_SETCURSEL, iKeySelected, 0); ReleaseDC (GetDlgItem (hDlg, IDC_SIGNKEYCOMBO), hdc); return (bAtLeastOneSecretKey); }
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 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 */
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; }
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 */
/***** * * verify_signature * * Call-out routine used by the CMS library for verifying a signature. * Parameters and return values defined in CMS docs. This uses the * PGP SDK. See "PGP Software Developer's Kit, Reference Manual" * for details on calls used here. * *****/ int x509CMSVerifyCallback ( unsigned char *data, size_t dataLen, unsigned char *sigalg, size_t algLen, unsigned char *params, size_t paramLen, unsigned char *signature, size_t sigLen, unsigned char *pubkey, size_t pubkeyLen, TC_CERT *issuer, void *verData, TC_CONTEXT *ctx) { X509CMSCallbackData *pgpData = (X509CMSCallbackData *) verData; PGPMemoryMgrRef mgrRef; PGPPublicKeyContextRef publicKey; PGPHashContextRef hash; PGPKeySetRef keySet; PGPKeyListRef klist; PGPKeyIterRef kiter; PGPKeyRef mykey; PGPError err; PGPByte *certData; PGPSize certDataLen; int rtn = -1; PGPHashAlgorithm hashAlg; (void) params; (void) paramLen; (void) pubkey; (void) pubkeyLen; do { /* check that the algorithm ID is allowed */ /* TODO... */ /* if we dont have the issuer's certificate, we can't verify the signature. */ /* PGPsdk needs to have a function that takes raw ASN.1 encoded key material and returns a KeyRef in order to support verification of PKCS10 requests */ if (!issuer) break; /* import the certificate into pgp */ tc_pack_cert (&certData, &certDataLen, issuer, ctx); /* import the key into a PGP key set */ err = PGPImportKeySet (pgpData->context, &keySet, PGPOX509Encoding (pgpData->context, 1), PGPOInputBuffer (pgpData->context, certData, certDataLen), PGPOLastOption (pgpData->context)); TC_Free (ctx->memMgr, certData); if (IsPGPError (err)) break; /* extract the key into a PGPKeyRef */ err = PGPOrderKeySet (keySet, kPGPAnyOrdering, &klist); if (IsPGPError (err)) break; err = PGPNewKeyIter (klist, &kiter); if (IsPGPError (err)) break; err = PGPKeyIterNext (kiter, &mykey); if (IsPGPError (err)) break; /* create the public key context */ err = PGPNewPublicKeyContext (mykey, kPGPPublicKeyMessageFormat_X509, &publicKey); if (IsPGPError (err)) break; hashAlg = x509HashAlgorithm (sigalg, algLen); /* create and calculate the hash, do not finalize hash for PGPPublicKeyVerify() call */ mgrRef = PGPGetContextMemoryMgr (pgpData->context); err = PGPNewHashContext (mgrRef, hashAlg, &hash); if (IsPGPError (err)) break; err = PGPContinueHash (hash, data, dataLen); if (IsPGPError (err)) break; err = PGPPublicKeyVerifySignature ( publicKey, hash, (void *)signature, sigLen); hash = NULL; if ( IsPGPError(err) ) break; rtn = 0; } while (0); /* clean-up */ PGPFreeKeyIter(kiter); PGPFreeKeyList(klist); PGPFreeKeySet(keySet); if (hash) PGPFreeHashContext(hash); PGPFreePublicKeyContext (publicKey); return rtn; } /* verify_signature */
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; }