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

📄 envelope.h

📁 cryptlib安全工具包
💻 H
📖 第 1 页 / 共 3 页
字号:
   on decoding them.  A typical complex enveloped type might contain a 
   number of headers, a session key encrypted with 18 different public keys, 
   five varieties of signature type, and God knows what else, of which the 
   caller might feed us 500 bytes - a small fraction of the total data - and 
   then ask for information on what they've just fed us.  We have to 
   remember how far we got (halfway through an RSA-encrypted DES key fifteen 
   levels of nesting down in an ASN.1 structure), process everything that we 
   can, and then get back to them on what we found.  Then they feed us 
   another few hundred bytes and the whole thing starts anew.

   The state machine works by processing one complete object or part of an
   object at a time and then moving on to the next state that corresponds to
   handling another part of the object or another object.  If there isn't
   enough data present to process a part or subpart, we return an underflow
   error and try again when more data is added */

typedef enum {
	DEENVSTATE_NONE,				/* No header processing/before header */

	/* Header state information */
	DEENVSTATE_SET_ENCR,			/* Processing start of SET OF EncrKeyInfo */
	DEENVSTATE_ENCR,				/* Processing EncrKeyInfo records */
	DEENVSTATE_ENCRCONTENT,			/* Processing EncrContentInfo */

	DEENVSTATE_SET_HASH,			/* Processing start of SET OF DigestAlgoID */
	DEENVSTATE_HASH,				/* Processing DigestAlgoID records */
	DEENVSTATE_CONTENT,				/* Processing ContentInfo */

	DEENVSTATE_DATA,				/* Processing data payload */

	/* Trailer state information */
	DEENVSTATE_CERTSET,				/* Processing optional cert chain */
	DEENVSTATE_SET_SIG,				/* Processing start of SET OF Signature */
	DEENVSTATE_SIG,					/* Processing Signature records */
	DEENVSTATE_EOC,					/* Processing end-of-contents octets */

	DEENVSTATE_DONE,				/* Finished processing header/trailer */

	DEENVSTATE_LAST					/* Last valid de-enveloping state */
	} DEENV_STATE;

/* The current state of processing of PGP headers that contain non-data in 
   the envelope during the de-enveloping process.  These are somewhat 
   different to the ASN.1-encoded objects used by cryptlib in that many of 
   the objects are emitted as discrete packets rather than the nested 
   objects used in ASN.1 objects.  This makes some parts of the processing
   much easier (less length information to track) and some parts much harder
   (since just about anything could appear next, you need to maintain a
   lookahead to figure out what to do next, but you may run out of data
   before you can determine which state is next).  The handling of content
   inside encrypted data is particularly messy since there's a plain-data
   header that has to be removed in a manner which is transparent to the
   user.
   
   The two de-enveloping encrypted-data states are almost identical except 
   for the fact that one performs PGP's odd IV resync while the other 
   doesn't, a requirement buried in the depths of two otherwise identical 
   text blocks in the RFC */

typedef enum {
	PGP_DEENVSTATE_NONE,			/* No message processing/before message */

	/* Header state information */
	PGP_DEENVSTATE_ENCR,			/* Encrypted data packet */
	PGP_DEENVSTATE_ENCR_MDC,		/* Encrypted data with MDC */

	PGP_DEENVSTATE_DATA,			/* Data */
	PGP_DEENVSTATE_DATA_HEADER,		/* Out-of-band data inside compressed data */

	PGP_DEENVSTATE_DONE,			/* Finished processing message */

	PGP_DEENVSTATE_LAST				/* Last valid de-enveloping state */
	} PGP_DEENV_STATE;

/* Envelope information flags.  These are:

	ENVELOPE_ISDEENVELOPE: The envelope is a de-enveloping envelope.

	ENVELOPE_DETACHED_SIG: The (signed data) envelope should generate a
			standalone detached signature rather than signed enveloped data.

	ENVELOPE_NOSIGNINGCERTS: When generating a S/MIME signed data, don't
			include the signing certificates with the data.

	ENVELOPE_ATTRONLY: The (signed data) envelope only contains authenticated
			attributes, but not actual data.  This is required by SCEP.

	ENVELOPE_ZSTREAMINITED: Whether the zlib compression/decompression stream
			has been initialised.
	
	ENVELOPE_AUTHENC: Use authenticated encryption, which adds a MAC tag to
			the encrypted data */

#define ENVELOPE_ISDEENVELOPE	0x0001	/* De-enveloping envelope */
#define ENVELOPE_DETACHED_SIG	0x0002	/* Generate detached signature */
#define ENVELOPE_NOSIGNINGCERTS	0x0004	/* Don't include signing certs */
#define ENVELOPE_ATTRONLY		0x0008	/* Env.contains only auth'd attrs.*/
#define ENVELOPE_ZSTREAMINITED	0x0010	/* Whether zlib stream has been inited */
#define ENVELOPE_AUTHENC		0x0020	/* Use authenticated encryption */

/* Envelope data processing flags.  These are:

	ENVDATA_HASINDEFTRAILER: The (signed) envelope trailer has an indefinite
			length due to the use of signature algorithms that produce 
			variable-length output that can't be determined in advance.

	ENVDATA_HASHACTIONSACTIVE: The (signed) envelope is currently hashing
			payload data.

	ENVDATA_NOLENGTHINFO: The payload uses neither a definite- nor 
			indefinite-length encoding but continues until the caller tells
			us it's finished.  This is used to handle PGP 2.x compressed
			data, which just continues until EOF with no length information
			provided.

	ENVDATA_NOSEGMENT: The payload data shouldn't be segmented because a
			definite-length encoding is being used.

	ENVDATA_SEGMENTCOMPLETE: An indefinite-length segment has been completed
			an another one must be begun before more payload data can be
			emitted.

	ENVDATA_ENDOFCONTENTS: The EOC octets on indefinite payload data have 
			been reached.

	ENVDATA_NEEDSPADDING: Before (encrypted) enveloping can been completed 
			the payload data needs PKCS #5 padding added to it.

	ENVDATA_HASATTACHEDOOB: The envelope has out-of-band additional data
			attached to the payload data.  This is used by OpenPGP to tack
			an MDC packet onto the end of encrypted data.

   The handling of several of these flags is quite complex, more details can 
   be found in encode/decode.c */

#define ENVDATA_HASINDEFTRAILER	0x01	/* Whether trailer size is indefinite */
#define ENVDATA_HASHACTIONSACTIVE 0x02	/* Payload hashing is active */
#define ENVDATA_NOLENGTHINFO	0x04	/* No length info for payload avail.*/
#define ENVDATA_NOSEGMENT		0x08	/* Don't segment payload data */
#define ENVDATA_SEGMENTCOMPLETE	0x10	/* Current segment has been completed */
#define ENVDATA_ENDOFCONTENTS	0x20	/* EOC reached */
#define ENVDATA_NEEDSPADDING	0x40	/* Whether to add PKCS #5 padding */
#define ENVDATA_HASATTACHEDOOB	0x80	/* Whether data has attached OOB extra */

/* Envelope data-copy flags.  These are:

	ENVCOPY_FLAG_NONE: Perform no special processing.

	ENVCOPY_FLAG_OOBDATA: Data is out-of-band data that isn't part of the 
			normal data payload */

#define ENVCOPY_FLAG_NONE		0x00	/* No special action */
#define ENVCOPY_FLAG_OOBDATA	0x01	/* Data is OOB rather than payload data */

/* The size of the buffer used to handle read-ahead into out-of-band data at 
   the start of the payload */

#define OOB_BUFFER_SIZE			8

/* The structure that stores the information on an envelope */

typedef struct EI {
	/* Control and status information */
	CRYPT_FORMAT_TYPE type;			/* Envelope type */
	CRYPT_CONTENT_TYPE contentType;	/* Inner content type */
	ACTION_TYPE usage;				/* Usage (signing, encryption, etc) */
	int version;					/* Protocol version/subtype */
	int flags;						/* Envelope information flags */
	int dataFlags;					/* Envelope data processing flags */

	/* The list of actions to perform on the data.  There are three sets of
	   actions, the preActions (key exchange), the main actions (encryption 
	   or hashing), and the postActions (signing) */
	ACTION_LIST *preActionList;
	ACTION_LIST *actionList;
	ACTION_LIST *postActionList;

	/* Several action groups produce information which is prepended or
	   appended to the data.  The following variables record the encoded size
	   of this information.  In some cases the size of the appended
	   information isn't known when the enveloping is started so we have to
	   use an indefinite-length encoding for the outermost wrapper, if this
	   is the case then we set the ENVDATA_HASINDEFTRAILER flag to indicate 
	   that a definite-length encoding shouldn't be used even if the payload 
	   size is known */
	int cryptActionSize;			/* Size of key exchange actions */
	int signActionSize;				/* Size of signatures */
	int extraDataSize;				/* Size of any extra data */

	/* When prepending or appending header or trailer information to an
	   envelope we need to record the current position in the action list so
	   that we can continue later if we run out of room */
	ACTION_LIST *lastAction;

	/* When de-enveloping we may have objects present that can't be used
	   until user-supplied de-enveloping information is added to the
	   envelope.  We store these in a linked list in memory until the
	   information needed to work with them is present.  We also store a
	   pointer to the current position in the list, which is used when
	   traversing the list */
	CONTENT_LIST *contentList, *contentListCurrent;

	/* The public-key encryption/private-key decryption and signature-check
	   keysets that are used to look up any keys required during the 
	   enveloping/de-enveloping process */
	CRYPT_KEYSET iDecryptionKeyset;
	CRYPT_KEYSET iEncryptionKeyset;
	CRYPT_KEYSET iSigCheckKeyset;

	/* When we're encrypting/decrypting the envelope payload, the one action 
	   that we'll be performing constantly is encryption.  Similarly, when
	   we're signing/sig.checking, we'll be hashing the payload.  In order 
	   to make this process more efficientm, we record the encryption and 
	   hashing info here to save having to pull it out of the action list 
	   whenever it's needed.
	   
	   The encryption context, of which there's only one, is stored here.
	   Note that since there is a second reference held in the action list, 
	   there's no need to explicitly delete this when we destroy the 
	   envelope object since it's already been destroyed when the action 
	   list is destroyed.

	   For hashing, we may have multiple hash contexts active, so we still
	   use the action list for these.  However it's convenient to have 
	   direct confirmation that we have to hash the payload data to save 
	   having to check the action list each time, so we set the
	   ENVDATA_HASHACTIONSACTIVE flag to indicate that hashing is taking 
	   place.  This is only set while the hashing is taking place, once 
	   there's no more data to be hashed it's cleared to prevent out-of-band 
	   data from being hashed as well */
	CRYPT_CONTEXT iCryptContext;

	/* Some types of key management/signature require additional certs.
	   For encryption, there may be originator certs present for use with
	   key agreement algorithms; for signing, there may be a signing-cert
	   meta-object present to contain the union of multiple sets of signing
	   certs if multiple signatures are present.  These are held in the 
	   following certificate object */
	CRYPT_CERTIFICATE iExtraCertChain;

	/* The encryption/hashing/signature defaults for this envelope.  These
	   are recorded here when the envelope is created (so that a later 
	   change of the default value won't affect the enveloping process) but 
	   can be changed explicitly on a per-envelope basis by setting the 
	   options just for the envelope rather than for all of cryptlib */
	CRYPT_ALGO_TYPE defaultHash;		/* Default hash algorithm */
	CRYPT_ALGO_TYPE defaultAlgo;		/* Default encryption algorithm */
	CRYPT_ALGO_TYPE defaultMAC;			/* Default MAC algorithm */

#ifdef USE_COMPRESSION
	/* zlib stream compression data structure used to hold the compression/
	   decompression state */
	z_stream zStream;				/* zlib state variable */
#endif /* USE_COMPRESSION */

	/* Buffer information */
	BUFFER( bufSize, bufPos ) \
	BYTE *buffer;					/* Data buffer */
	int bufSize;					/* Total buffer size */
	int bufPos;						/* Last data position in buffer */

	/* Auxiliary buffer used as a staging area for holding signature data 
	   that may not currently fit into the main buffer.  These are generated 
	   into the auxiliary buffer and then copied into the main buffer as 
	   required */
	BUFFER_OPT( auxBufSize, auxBufPos ) \
	BYTE *auxBuffer;				/* Buffer for sig.data */
	int auxBufSize, auxBufPos;		/* Current pos and total aux.buf.size */

	/* When the caller knows in advance how large the payload will be, they 
	   can advise the enveloping code of this, which allows a more efficient 
	   encoding of the data.  The following variable records the payload 
	   size */
	long payloadSize;

	/* The current state of header processing.  The cryptlib/CMS and PGP
	   processing states are kept separate (although they could actually be 
	   merged into the same variable) because they are conceptually separate 
	   and shouldn't really be treated as the same thing */
	ENVELOPE_STATE state;			/* Current state of processing */
	ENV_STATE envState;				/* Current state of env.non-data proc.*/
	DEENV_STATE deenvState;			/* Current state of de-env.non-data proc.*/
#ifdef USE_PGP
	PGP_DEENV_STATE pgpDeenvState;	/* Current state of PGP de-env.n-d proc.*/
#endif /* USE_PGP */
	long hdrSetLength;				/* Remaining bytes in SET OF EKeyInfo */

	/* Some data formats place out-of-band data at the start of the payload
	   rather than putting it in the header, the data-left variable keeps
	   track of how many bytes of data still need to be removed before we
	   can return actual payload data to the caller.  In some cases the 
	   amount of data can't be specified as a simple byte count but involves 
	   format-specific events (e.g. the presence of a flag or data count in 

⌨️ 快捷键说明

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