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

📄 pgpdecode.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 5 页
字号:

					/* Try decrypting the ESK */
					err = pgpEskPKdecrypt (esk, decKey, s->passPhrase,
										   s->passLength, s->hashedPhrase,
										   s->cacheTimeOut, s->cacheGlobal,
										   &key );
					if( err == kPGPError_BadPassphrase ||
						pgpIsKeyRelatedError( err ) )
					{
						/* Pass phrase failed to unlock.  Try next ESK. */
						if( firstpass ) {
							/* Accumulate decryption keys into decKeySet */
							if( IsPGPError( err = PGPAddKey(decKey,decKeySet)))
								goto error;
						}
						break;
					}
					if (err <= 0) {
						/* Key was on token before 
						   but now there some problem with the token */
						if( bOnToken && err == kPGPError_KeyUnusableForEncryption )
							break;

						/* Failed to decrypt, indicates corrupt ESK */
						if (err != kPGPError_CAPIUnsupportedKey)
							err = kPGPError_CorruptSessionKey;
						goto error;
					}
					keylen = err;
				}

				/* 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( IsntNull( key ) )
			{
				PGPFreeData( key );
				key = NULL;
			}
		}
		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;
			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->cacheTimeOut, &s->cacheGlobal,
				  &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( keyIDArray ) ) {
		PGPFreeData( keyIDArray );
		keyIDArray = NULL;
	}
	if( IsntNull( key ) ) {
		PGPFreeData( key );
		key = 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_CachePassphrase,
	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_KeyDBRef,
	kPGPOptionType_RecursivelyDecode,
	kPGPOptionType_InputFormat,
	kPGPOptionType_X509Encoding,   /* allow calling from pgpimportkeydb */
	kPGPOptionType_DataIsASCII
};

/* 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 */
	PGPBoolean			 bLargeFile;
	PGPError			 err2 = kPGPError_NoErr;
	
	/* 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 keydb, passphrase data from user */
	if( IsPGPError( s->err = pgpSetupKeyDB( s->optionList,
									&s->keyDB ) ) )
		goto error;
	if( IsPGPError( s->err = pgpSetupDecodePassphrase( s->context,
						s->optionList, &s->passPhrase, &s->passLength,
						&s->hashedPhrase, &s->cacheTimeOut, &s->cacheGlobal,
						&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, &bLargeFile, &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 ) {
		if( IsntNull( *s->prevOutput ) )
			(*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 error is used to abort early in the process */
	if( s->err == kPGPError_Interrupted )
		s->err = kPGPError_NoErr;

	/* Notify user via callback of error if requested */
	if( IsPGPError( s->err ) && IsntNull( s->func ) ) {
		(void)pgpEventError( s->context, &s->newOptionList, s->func,
							 s->userValue, s->err, NULL );
		pgpCleanupOptionList( &s->newOptionList );
	}
		
	err2 = pgpEventFinal( s->context, &s->newOptionList, s->func,
						 s->userValue );

	if( IsPGPError( err2 ) ) {
		s->err = err2;
	}

	pgpCleanupOptionList( &s->newOptionList );

	return s->err;
}



/************************** X509 decode function ****************************/


	static PGPError
sDecodeInputX509(
	PGPDecodeJob		 *s
	)
{
	PGPKeyDBObjRef		signKey;
	PGPKeyDBObjRef		decryptKey;
	PGPBoolean			isSigned;
	PGPBoolean			sigChecked;
	PGPBoolean			sigVerified;
	PGPBoolean			fMustFreeBuf;
	PGPBoolean			fMoreData;
	const PGPTime		sigCreationTime = 0;
	const PGPUInt32		sigExpirationPeriod = 0;
	PGPAttributeValue	*extraData;
	PGPUInt32			extraDataLength;
	PGPByte				*certSet = NULL;
	PGPSize				certSetLength;
	PGPByte				*crlSet = NULL;
	PGPSize				crlSetLength;
	PGPKeyDBRef			importKeyDB;
	PGPKeyDBRef			newKeyDB = NULL;
	PGPOption			passop;
	PGPOptionListRef	passphrase = NULL;
	PGPByte				*inBufPtr;
	PGPSize				inBufLength;
	PGPInputFormat		inputFormat;

	/* There must be a keydb to import keys to */
	if( IsPGPError( s->err = pgpFindOptionArgs( s->optionList,
						 kPGPOptionType_ImportKeysTo, TRUE,
						 "%p", &importKeyDB ) ) )
		return s->err;

	/* Send initial events */
	s->err = pgpEventBeginLex( s->context, &s->newOptionList,
							   s->func, s->userValue, s->sectionNumber,
							   s->sectOffset );
	pgpCleanupOptionList( &s->newOptionList );
	if( IsPGPError( s->err ) )
		return s->err;

	s->analyzeType = kPGPAnalyze_X509Certificate;
	s->err = pgpEventAnalyze( s->context, &s->newOptionList,
							  s->func, s->userValue, s->analyzeType );
	pgpCleanupOptionList( &s->newOptionList );
	if( IsPGPError( s->err ) )
		return s->err;
	
	/* Ge

⌨️ 快捷键说明

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