⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpdecode.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
						err = klen;
						goto error;
					}
					/* Else klen is length of key */
					*keylen = klen;
				}

				/* Returns 0 on success, nonzero on failure */
				if( tryKey (tryarg, key, *keylen) == 0 ) {
					/* Success */
					success = 1;
					/* Report it worked OK */
					cipheralg = (PGPCipherAlgorithm)key[0];
					if( IsPGPError( err = pgpEventDecryption( s->context,
										  &s->newOptionList, s->func,
										  s->userValue, cipheralg,
										  key, *keylen) ) )
						goto error;
					pgpCleanupOptionList( &s->newOptionList );
				}
				break;

			case PGP_ESKTYPE_PUBKEY:
			{
				PGPKeyID			keyid;		/* Key ID from ESK */
			
				if (s->passPhraseIsSessionKey) {
					*keylen = pgpMin( *keylen, s->passLength );
					pgpCopyMemory( s->passPhrase, key, *keylen );
				} else {
					/* Look up key from ESK */
					err = pgpGetEskKeyID( esk, &keyid );
					if ( IsPGPError( err ) )
						goto error;

					pkalg = (PGPPublicKeyAlgorithm)pgpEskPKAlg (esk);

					/* If don't have key, go on to next one */
					decKey = NULL;
					if( IsntNull( s->keySet ) &&
							pkalg >= kPGPPublicKeyAlgorithm_First &&
							pkalg <= kPGPPublicKeyAlgorithm_Last) {
						(void)PGPGetKeyByKeyID( s->keySet, &keyid,
												pkalg, &decKey);
					}

					if( IsNull( decKey ) )
						break;

					if( IsPGPError( err = pgpGetKeyRingSet( decKey, FALSE,
															&ringSet ) ) )
						goto error;

					/*
					 * Use lower-level function to look up proper subkey.
					 * If key has more than one subkey then ringSecSecKey won't
					 * choose the right one if we give it a top level key.
					 */
					ringKey = ringKeyById8 (ringSet, (PGPByte)pkalg,
											pgpGetKeyBytes (&keyid));
					if( IsNull( ringKey ) )
						break;

					seckey = ringSecSecKey( ringSet, ringKey,
											PGP_PKUSE_ENCRYPT );

					/* See if have a good decryption key */
					if (seckey && !seckey->decrypt) {
						/* A matching secret key which can't decrypt? */
						pgpSecKeyDestroy (seckey);
						seckey = NULL;
					}

					if( IsNull( seckey ) )
						break;

					/* Try to unlock decryption key with passphrase */
					err = pgpSecKeyUnlock (seckey, s->env,
									(char *)s->passPhrase, s->passLength,
									s->hashedPhrase );
					if (err <= 0) {
						/* Pass phrase failed to unlock.  Try next ESK. */
						pgpSecKeyDestroy (seckey);
						seckey = NULL;
						if( firstpass ) {
							/* Accumulate decryption keys into decKeySet */
							if( IsPGPError( err = PGPNewSingletonKeySet(
													decKey, &decKeySet1 ) ) )
								goto error;
							if( IsPGPError( err = PGPAddKeys(decKeySet1,
															 decKeySet ) ) )
								goto error;
							PGPFreeKeySet( decKeySet1 );
							decKeySet1 = NULL;
						}
						break;
					}

					/* Try decrypting the ESK */
					err = pgpEskPKdecrypt (esk, s->env, seckey, key);
					*keylen = err;
					pgpSecKeyDestroy (seckey);
					seckey = NULL;
					if (err <= 0) {
						/* Failed to decrypt, indicates corrupt ESK */
						if (err != kPGPError_CAPIUnsupportedKey)
							err = kPGPError_CorruptSessionKey;
						goto error;
					}
				}

				/* Now try the decrypted ESK against the rest of the message */
				/* (save cipheralgorithm, first byte of key buffer) */
				cipheralg = (PGPCipherAlgorithm)key[0];
				err = tryKey (tryarg, key, *keylen);
				if (err) {
					/* Failure, indicates corrupt ESK */
					err = kPGPError_CorruptSessionKey;
					goto error;
				}
				
				/* Else it worked OK */
				if( IsPGPError( err = pgpEventDecryption( s->context,
									  &s->newOptionList, s->func,
									  s->userValue, cipheralg,
									  key, *keylen) ) )
					goto error;
				pgpCleanupOptionList( &s->newOptionList );
				
				success = 1;
				break;
			}

			default:
				/* Unknown ESK type */
				pgpAssert (0);
				break;
			}
		}
		if( !success ) {
			/* Get new passphrase from user */
			if( IsNull( s->func ) ) {
				/* If no callback, just skip undecryptable messages */
				err = PGPANN_PARSER_EATIT;
				goto error;
			}
			if( firstpass ) {
				firstpass = FALSE;
				/* Remove any irrelevant subkeys from key we add */
				if( IsPGPError( err = sRemoveUnlistedSubkeys( decKeySet,
															  keyIDArray,
															  keyIDCount ) ) )
					goto error;
			}
			if( IsPGPError( err = pgpEventPassphrase( s->context,
								  &s->newOptionList, s->func,
								  s->userValue,
								  (PGPBoolean)(passPhraseCount>0),
								  decKeySet ) ) )
				goto error;
			pgpBurnDecodePassphrase( s );
			err = pgpSetupDecodePassphrase( s->context,
				  s->newOptionList, &s->passPhrase, &s->passLength,
				  &s->hashedPhrase, &s->passPhraseIsSessionKey );
			pgpCleanupOptionList( &s->newOptionList );
			if( IsPGPError( err ) )
				goto error;
			/* If he specified no passphrase, we will eat the message */
			if( IsNull( s->passPhrase ) ) {
				err = PGPANN_PARSER_EATIT;
				goto error;
			}
		}
	}

	err = kPGPError_NoErr;

error:
	if( IsntNull( decKeySet ) ) {
		PGPFreeKeySet( decKeySet );
		decKeySet = NULL;
	}
	if( IsntNull( decKeySet1 ) ) {
		PGPFreeKeySet( decKeySet1 );
		decKeySet1 = NULL;
	}
	if( IsntNull( seckey ) ) {
		pgpSecKeyDestroy( seckey );
		seckey = NULL;
	}
	if( IsntNull( keyIDArray ) ) {
		pgpContextMemFree( s->context, keyIDArray );
		keyIDArray = NULL;
	}

	return err;

#endif /* PGP_DECRYPT_DISABLE */ /* ] */
}


/************************** Main decode function ****************************/



static const PGPOptionType decodeOptionSet[] = {
	kPGPOptionType_InputFileRef,
	kPGPOptionType_InputBuffer,
	kPGPOptionType_OutputFileRef,
	kPGPOptionType_OutputBuffer,
	kPGPOptionType_OutputAllocatedBuffer,
	kPGPOptionType_AppendOutput,
	kPGPOptionType_DiscardOutput,
	kPGPOptionType_LocalEncoding,
	kPGPOptionType_Passphrase,
	kPGPOptionType_Passkey,
	kPGPOptionType_SessionKey,
	kPGPOptionType_DetachedSignature,
	kPGPOptionType_FailBelowValidity,
	kPGPOptionType_WarnBelowValidity,
	kPGPOptionType_OutputLineEndType,
	kPGPOptionType_EventHandler,
	kPGPOptionType_SendNullEvents,
	kPGPOptionType_ImportKeysTo,
	kPGPOptionType_SendEventIfKeyFound,
	kPGPOptionType_DecodeOnlyOne,
	kPGPOptionType_PassThroughIfUnrecognized,
	kPGPOptionType_PassThroughClearSigned,
	kPGPOptionType_PassThroughKeys,
	kPGPOptionType_KeySetRef,
	kPGPOptionType_RecursivelyDecode,
	kPGPOptionType_InputFormat,
	kPGPOptionType_X509Encoding   /* allow calling from pgpimportkeyset */
};

/* Main entry point for this module */

	PGPError
pgpDecodeInternal(
	PGPContextRef		context,
	PGPOptionListRef	optionList
	)
{
	PGPDecodeJob		 jobState,		/* State in a struct */
						*s=&jobState;	/* Use s-> to access all state  */
	PGPFileDataType		 inFileDataType;	/* Unused */
	
	/* Initialize pointers to NULL for easier error cleanup */
	pgpClearMemory( s, sizeof( *s ) );
	s->context = context;
	s->optionList = optionList;
	s->tail = &s->head;
	s->analyzeState = kAnalyzeWaiting;

	if (IsPGPError( s->err = pgpCheckOptionsInSet( optionList,
						decodeOptionSet, elemsof( decodeOptionSet ) ) ) )
		return s->err;

	/* Get copies of info from context */
	s->env = pgpContextGetEnvironment( s->context );
	s->rng = pgpContextGetX9_17RandomContext ( s->context );
	
	/* Setup the UI callback functions & args */
	s->ui.message		= pgpDecodeShowMessage;
	s->ui.doCommit		= pgpDecodeDoCommit;
	s->ui.newOutput		= pgpDecodeSetupNewOutput;
	s->ui.needInput		= pgpDecodeFindAltInput;
	s->ui.sigVerify		= pgpDecodeVerifySig;
	s->ui.eskDecrypt	= pgpDecodeDecryptESK;
	s->ui.annotate		= pgpDecodeHandleAnnotation;

	/* Set up callback pointers and data */
	if( IsPGPError( s->err = pgpSetupCallback( s->optionList,
							 &s->func, &s->userValue, &s->fNullEvents ) ) )
		goto error;
	s->err = pgpEventInitial( s->context, &s->newOptionList,
							  s->func, s->userValue );
	pgpCleanupOptionList( &s->newOptionList );
	if( IsPGPError( s->err ) )
		goto error;

	/* Get keyset, passphrase data from user */
	if( IsPGPError( s->err = pgpSetupKeySet( s->optionList,
									&s->keySet ) ) )
		goto error;
	if( IsPGPError( s->err = pgpSetupDecodePassphrase( s->context,
						s->optionList, &s->passPhrase, &s->passLength,
						&s->hashedPhrase, &s->passPhraseIsSessionKey ) ) )
		goto error;

	/* Check input format and handle X.509 related formats */
	if( IsPGPError( s->err = pgpFindOptionArgs( s->optionList,
						 kPGPOptionType_InputFormat, FALSE,
						 "%d", &s->inputFormat ) ) )
		goto error;
	if( s->inputFormat >= kPGPInputFormat_X509DataInPKCS7 ) {
		/* Handle input X.509 data */
		s->err = sDecodeInputX509 (s);
		goto error;
	}

	/* Set up input file or buffer */
	if( IsPGPError( s->err = pgpSetupInput( s->context, s->optionList,
					NULL, NULL, FALSE, FALSE, &s->inFileRef, &s->pfrin,
					&inFileDataType, &s->inBufPtr, &s->inBufLength ) ) )
		goto error;


	/* Parse output information if any */
	if( IsPGPError( s->err = pgpSetupOutput( s->optionList,
							s->env, &s->outFileRef,
							&s->outBufPtr, &s->outBufPtrPtr,
							&s->outBufMaxLength, &s->outBufUsedLength,
							&s->outDiscard, &s->localEncodeFlags,
							&s->lineEnd, &s->fAppendOutput ) ) )
		goto error;

	/* If he set up output already, keep it throughout.  Otherwise we need
	 * to see a callback function. */
	s->fixedOutput = IsntNull( s->outFileRef ) || IsntNull( s->outBufPtr ) ||
					  IsntNull( s->outBufPtrPtr ) || s->outDiscard;

	if( !s->fixedOutput && IsNull( s->func ) ) {
		pgpDebugMsg( "Error: no output options" );
		s->err = kPGPError_BadParams;
		goto error;
	}

	/* Set up pipeline */
	s->tail = pgpDecryptPipelineCreate ( context,
				&s->head, s->env, NULL, &s->ui, s);

	/* Handle clearsign and key passthroughs (nonpgp is in NewOutput) */
	if( IsPGPError( s->err = pgpSetupPassThrough( s->context, s->optionList,
												  s->head,
												  &s->passThroughFifo,
												  &s->recurse ) ) )
		goto error;

	/* Now pump the data through the pipes */
	if( s->inFileRef ) {
		/* File input */
		if( IsntNull( s->func ) && s->fNullEvents ) {
			pgpFileReadSetCallBack( s->pfrin, decodeLocalCallBack, s );
		}
		s->err = pgpFileReadPump( s->pfrin, s->head );
		pgpFileReadDestroy( s->pfrin );
		s->pfrin = NULL;
		if( IsPGPError( s->err ) )
			goto error;
		s->head->sizeAdvise( s->head, 0 );
	} else {
		/* Buffer input */
		if( IsntNull( s->func ) && s->fNullEvents ) {
			s->err = pgpPumpMem( s->head, s->inBufPtr, s->inBufLength,
								 decodeLocalCallBack, s );
		} else {
			s->err = pgpPumpMem( s->head, s->inBufPtr, s->inBufLength,
								 NULL, NULL );
		}
		if( IsPGPError( s->err ) )
			goto error;
	}

	/* Clean up if we had diverted the output in the last section */
	if( s->fPrevOutput ) {
		(*s->prevOutput)->teardown( *s->prevOutput );
		sRestoreOutputState( s, s->prevOutput );
	}

	/* Get output buffer bytes-used info if appropriate */
	if( s->outPipe ) {
		if( IsntNull( s->outBufPtrPtr ) ) {
			/* Dynamically allocated buffer - tell user size & position */
			if( IsPGPError( s->err = pgpGetVariableMemOutput( s->outPipe,
							s->outBufMaxLength, s->outBufPtrPtr,
							s->outBufUsedLength ) ) )
				goto error;
		} else {
			/* Fixed size buffer - tell user actual size used */
			pgpAssert( IsntNull( s->outBufPtr ) );
			if( IsPGPError( s->err = pgpGetMemOutput( s->outPipe,
						s->outBufMaxLength, s->outBufUsedLength ) ) )
				goto error;
		}
		s->outPipe = NULL;
	}

	/* Now we can tear down the pipeline */
	s->head->teardown( s->head );
	s->head = NULL;
	if( IsntNull( s->pfout ) ) {
		pgpFileClose( s->pfout );
		s->pfout = NULL;
	}

	/* Done, clean up and return */
	s->err = kPGPError_NoErr;

error:

	if( IsntNull( s->head ) ) {
		s->head->teardown( s->head );
		s->head = NULL;
	}
	if( IsntNull( s->pfrin ) ) {
		pgpFileReadDestroy( s->pfrin );
		s->pfrin = NULL;
	}
	if( IsntNull( s->pfout ) ) {
		pgpFileClose( s->pfout );
		s->pfout = NULL;
	}
	if( IsntNull( s->outFileRef ) ) {
		PFLFreeFileSpec( s->outFileRef );
		s->outFileRef = NULL;
	}

	if( IsntNull( s->passThroughFifo ) ) {
		pgpFifoDestroy( &pgpByteFifoDesc, s->passThroughFifo );
		s->passThroughFifo = NULL;
	}

	/* Burn passphrase from job structure, if any */
	pgpBurnDecodePassphrase( s );

	/* Interruption erro

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -