cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
pgp_denv.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib PGP De-enveloping Routines *
4 * Copyright Peter Gutmann 1996-2008 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "pgp_rw.h"
10  #include "envelope.h"
11 #else
12  #include "enc_dec/pgp_rw.h"
13  #include "envelope/envelope.h"
14 #endif /* Compiler-specific includes */
15 
16 #ifdef USE_PGP
17 
18 /****************************************************************************
19 * *
20 * Utility Routines *
21 * *
22 ****************************************************************************/
23 
24 /* Sanity-check the envelope state */
25 
27 static BOOLEAN sanityCheck( const ENVELOPE_INFO *envelopeInfoPtr )
28  {
29  /* Make sure that general envelope state is in order */
30  if( !( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE ) )
31  return( FALSE );
32  if( envelopeInfoPtr->pgpDeenvState < PGP_DEENVSTATE_NONE || \
33  envelopeInfoPtr->pgpDeenvState >= PGP_DEENVSTATE_LAST )
34  return( FALSE );
35 
36  /* Make sure that the buffer position is within bounds */
37  if( envelopeInfoPtr->buffer == NULL || \
38  envelopeInfoPtr->bufPos < 0 || \
39  envelopeInfoPtr->bufPos > envelopeInfoPtr->bufSize || \
40  envelopeInfoPtr->bufSize < MIN_BUFFER_SIZE || \
41  envelopeInfoPtr->bufSize >= MAX_INTLENGTH )
42  return( FALSE );
43 
44  /* Make sure that the payload size is within bounds */
45  if( envelopeInfoPtr->payloadSize != CRYPT_UNUSED && \
46  ( envelopeInfoPtr->payloadSize < 0 || \
47  envelopeInfoPtr->payloadSize >= MAX_INTLENGTH ) )
48  return( FALSE );
49 
50  /* Make sure that the out-of-band buffer state is OK. The oobDataLeft
51  value is the general size of a data packet header plus the maximum
52  possible length for the variable-length filename portion */
53  if( envelopeInfoPtr->oobEventCount < 0 || \
54  envelopeInfoPtr->oobEventCount > 10 || \
55  envelopeInfoPtr->oobDataLeft < 0 || \
56  envelopeInfoPtr->oobDataLeft >= 32 + 256 )
57  return( FALSE );
58 
59  /* Make sure that the packet data information is within bounds */
60  if( envelopeInfoPtr->segmentSize < 0 || \
61  envelopeInfoPtr->segmentSize >= MAX_INTLENGTH || \
62  envelopeInfoPtr->dataLeft < 0 || \
63  envelopeInfoPtr->dataLeft >= MAX_INTLENGTH )
64  return( FALSE );
65 
66  return( TRUE );
67  }
68 
69 /* Get information on a PGP data packet. If the isIndefinite value is
70  present then an indefinite length (i.e. partial packet lengths) is
71  permitted, otherwise it isn't. If the allowDummyPackets flag is set then
72  we allow shorter-than-normal dummy packets (PGP_PACKET_MARKER), otherwise
73  we enforce a sensible minimum packet size */
74 
75 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 4 ) ) \
76 static int getPacketInfo( INOUT STREAM *stream,
77  INOUT ENVELOPE_INFO *envelopeInfoPtr,
78  OUT_ENUM_OPT( PGP_PACKET ) PGP_PACKET_TYPE *packetType,
79  OUT_LENGTH_Z long *length,
80  OUT_OPT_BOOL BOOLEAN *isIndefinite,
81  IN_LENGTH_SHORT int minPacketSize )
82  {
83  int ctb, version, status;
84 
85  assert( isWritePtr( stream, sizeof( STREAM ) ) );
86  assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
87  assert( isWritePtr( packetType, sizeof( PGP_PACKET_TYPE ) ) );
88  assert( isWritePtr( length, sizeof( long ) ) );
89  assert( isIndefinite == NULL || \
90  isWritePtr( isIndefinite, sizeof( BOOLEAN ) ) );
91 
92  ENSURES( minPacketSize > 0 && minPacketSize < MAX_INTLENGTH_SHORT );
93 
94  /* Clear return values */
95  *packetType = PGP_PACKET_NONE;
96  *length = 0;
97  if( isIndefinite != NULL )
98  *isIndefinite = FALSE;
99 
100  /* Read the packet header and extract information from the CTB. The
101  assignment of version numbers is a bit complicated since it's
102  possible to use PGP 2.x packet headers to wrap up OpenPGP packets,
103  and in fact a number of apps mix version numbers. We treat the
104  version to report as the highest one that we find */
105  if( isIndefinite != NULL )
106  status = pgpReadPacketHeaderI( stream, &ctb, length, minPacketSize );
107  else
108  status = pgpReadPacketHeader( stream, &ctb, length, minPacketSize );
109  if( cryptStatusError( status ) )
110  {
111  if( status != OK_SPECIAL )
112  return( status );
113  ENSURES( isIndefinite != NULL );
114 
115  /* Remember that the packet uses an indefinite-length encoding */
116  envelopeInfoPtr->dataFlags &= ~ENVDATA_NOSEGMENT;
117  *isIndefinite = TRUE;
118  }
119  version = pgpGetPacketVersion( ctb );
120  if( version > envelopeInfoPtr->version )
121  envelopeInfoPtr->version = version;
122  *packetType = pgpGetPacketType( ctb );
123 
124  /* Extract and return the packet type */
125  return( CRYPT_OK );
126  }
127 
128 /****************************************************************************
129 * *
130 * Read Key Exchange/Signature Packets *
131 * *
132 ****************************************************************************/
133 
134 /* Add information about an object to an envelope's content information list */
135 
137 static int addContentListItem( INOUT ENVELOPE_INFO *envelopeInfoPtr,
138  INOUT_OPT STREAM *stream,
139  const BOOLEAN isContinuedSignature )
140  {
143  void *object = NULL;
144  int objectSize = 0, status;
145 
146  assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
147  assert( ( stream == NULL && \
148  envelopeInfoPtr->actionList == NULL && \
149  envelopeInfoPtr->contentList == NULL ) || \
150  isWritePtr( stream, sizeof( STREAM ) ) );
151 
152  REQUIRES( ( stream == NULL && \
153  envelopeInfoPtr->actionList == NULL && \
154  envelopeInfoPtr->contentList == NULL ) || \
155  ( stream != NULL ) );
156 
157  /* Make sure that there's room to add another list item */
158  if( !moreContentItemsPossible( envelopeInfoPtr->contentList ) )
159  return( CRYPT_ERROR_OVERFLOW );
160 
161  /* PGP 2.x password-encrypted data is detected by the absence of any
162  other keying object rather than by finding a concrete object type so
163  if we're passed a null stream we add a password pseudo-object */
164  if( stream == NULL )
165  {
166  CONTENT_ENCR_INFO *encrInfo;
167 
168  status = createContentListItem( &contentListItem,
169  envelopeInfoPtr->memPoolState,
171  NULL, 0 );
172  if( cryptStatusError( status ) )
173  return( status );
174  encrInfo = &contentListItem->clEncrInfo;
175  contentListItem->envInfo = CRYPT_ENVINFO_PASSWORD;
176  encrInfo->cryptAlgo = CRYPT_ALGO_IDEA;
177  encrInfo->cryptMode = CRYPT_MODE_CFB;
178  encrInfo->keySetupAlgo = CRYPT_ALGO_MD5;
179  status = appendContentListItem( envelopeInfoPtr, contentListItem );
180  if( cryptStatusError( status ) )
181  {
182  clFree( "addContentListItem", contentListItem );
183  return( status );
184  }
185  return( CRYPT_OK );
186  }
187 
188  /* Find the size of the object, allocate a buffer for it if necessary,
189  and copy it across. This call verifies that all of the object data
190  is present in the stream so in theory we don't have to check the
191  following reads, but we check them anyway just to be sure */
192  status = queryPgpObject( stream, &queryInfo );
193  if( cryptStatusError( status ) )
194  return( status );
195  if( queryInfo.type == CRYPT_OBJECT_SIGNATURE && \
196  queryInfo.dataStart <= 0 )
197  {
198  ENSURES( !isContinuedSignature );
199 
200  /* It's a one-pass signature packet, the signature information
201  follows in another packet that will be added later */
202  status = sSkip( stream, ( int ) queryInfo.size );
203  if( cryptStatusError( status ) )
204  return( status );
205  }
206  else
207  {
208  objectSize = ( int ) queryInfo.size;
209  if( ( object = clAlloc( "addContentListItem", \
210  objectSize ) ) == NULL )
211  return( CRYPT_ERROR_MEMORY );
212  status = sread( stream, object, objectSize );
213  if( cryptStatusError( status ) )
214  {
215  clFree( "addContentListItem", object );
216  return( status );
217  }
218  }
219 
220  /* If it's the rest of the signature data from a one-pass signature,
221  locate the first half of the signature info and complete the
222  information. In theory this could get ugly because there could be
223  multiple one-pass signature packets present but PGP handles multiple
224  signatures by nesting them so this isn't a problem */
225  if( isContinuedSignature )
226  {
227  int iterationCount;
228 
229  for( contentListItem = envelopeInfoPtr->contentList, \
230  iterationCount = 0;
231  contentListItem != NULL && \
232  contentListItem->envInfo != CRYPT_ENVINFO_SIGNATURE && \
233  iterationCount < FAILSAFE_ITERATIONS_MED;
234  contentListItem = contentListItem->next, iterationCount++ );
235  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
236  ENSURES( contentListItem != NULL && \
237  contentListItem->object == NULL && \
238  contentListItem->objectSize == 0 );
239 
240  /* Consistency check, make sure that the hash algorithm and key ID
241  that we've been working with match what's in the signature */
242  if( contentListItem->clSigInfo.hashAlgo != queryInfo.hashAlgo || \
243  contentListItem->keyIDsize != queryInfo.keyIDlength || \
244  memcmp( contentListItem->keyID, queryInfo.keyID,
245  queryInfo.keyIDlength ) )
246  {
247  clFree( "addContentListItem", object );
248  return( CRYPT_ERROR_BADDATA );
249  }
250 
251  /* We've got the right content list entry, point it to the newly-
252  acquired signature data */
253  contentListItem->object = object;
254  contentListItem->objectSize = objectSize;
255  }
256  else
257  {
258  /* Allocate memory for the new content list item and copy information
259  on the item across */
260  status = createContentListItem( &contentListItem,
261  envelopeInfoPtr->memPoolState,
262  ( queryInfo.type == CRYPT_OBJECT_SIGNATURE ) ? \
264  CRYPT_FORMAT_PGP, object, objectSize );
265  if( cryptStatusError( status ) )
266  {
267  if( object != NULL )
268  clFree( "addContentListItem", object );
269  return( status );
270  }
271  }
272  if( queryInfo.type == CRYPT_OBJECT_PKCENCRYPTED_KEY || \
273  queryInfo.type == CRYPT_OBJECT_SIGNATURE )
274  {
275  /* Remember details of the enveloping info that we require to
276  continue */
277  if( queryInfo.type == CRYPT_OBJECT_PKCENCRYPTED_KEY )
278  {
279  CONTENT_ENCR_INFO *encrInfo = &contentListItem->clEncrInfo;
280 
281  contentListItem->envInfo = CRYPT_ENVINFO_PRIVATEKEY;
282  encrInfo->cryptAlgo = queryInfo.cryptAlgo;
283  }
284  else
285  {
286  CONTENT_SIG_INFO *sigInfo = &contentListItem->clSigInfo;
287 
288  contentListItem->envInfo = CRYPT_ENVINFO_SIGNATURE;
289  sigInfo->hashAlgo = queryInfo.hashAlgo;
290  if( queryInfo.attributeStart > 0 )
291  {
292  REQUIRES( rangeCheck( queryInfo.attributeStart,
293  queryInfo.attributeLength,
294  objectSize ) );
295  sigInfo->extraData = \
296  ( BYTE * ) contentListItem->object + \
297  queryInfo.attributeStart;
298  sigInfo->extraDataLength = queryInfo.attributeLength;
299  }
300  if( queryInfo.unauthAttributeStart > 0 )
301  {
303  queryInfo.unauthAttributeLength,
304  objectSize ) );
305  sigInfo->extraData2 = \
306  ( BYTE * ) contentListItem->object + \
307  queryInfo.unauthAttributeStart;
308  sigInfo->extraData2Length = queryInfo.unauthAttributeLength;
309  }
310  }
311  REQUIRES( queryInfo.keyIDlength > 0 && \
312  queryInfo.keyIDlength <= CRYPT_MAX_HASHSIZE );
313  memcpy( contentListItem->keyID, queryInfo.keyID,
314  queryInfo.keyIDlength );
315  contentListItem->keyIDsize = queryInfo.keyIDlength;
316  if( queryInfo.iAndSStart > 0 )
317  {
318  REQUIRES( rangeCheck( queryInfo.iAndSStart,
319  queryInfo.iAndSLength, objectSize ) );
320  contentListItem->issuerAndSerialNumber = \
321  ( BYTE * ) contentListItem->object + queryInfo.iAndSStart;
322  contentListItem->issuerAndSerialNumberSize = queryInfo.iAndSLength;
323  }
324  }
325  if( queryInfo.type == CRYPT_OBJECT_ENCRYPTED_KEY )
326  {
327  CONTENT_ENCR_INFO *encrInfo = &contentListItem->clEncrInfo;
328 
329  /* Remember details of the enveloping info that we require to
330  continue */
331  if( queryInfo.keySetupAlgo != CRYPT_ALGO_NONE )
332  {
333  contentListItem->envInfo = CRYPT_ENVINFO_PASSWORD;
334  encrInfo->keySetupAlgo = queryInfo.keySetupAlgo;
335  encrInfo->keySetupIterations = queryInfo.keySetupIterations;
336  REQUIRES( queryInfo.saltLength > 0 && \
337  queryInfo.saltLength <= CRYPT_MAX_IVSIZE );
338  memcpy( encrInfo->saltOrIV, queryInfo.salt,
339  queryInfo.saltLength );
340  encrInfo->saltOrIVsize = queryInfo.saltLength;
341  }
342  else
343  contentListItem->envInfo = CRYPT_ENVINFO_KEY;
344  encrInfo->cryptAlgo = queryInfo.cryptAlgo;
345  encrInfo->cryptMode = CRYPT_MODE_CFB;
346  }
347  if( queryInfo.dataStart > 0 )
348  {
349  REQUIRES( rangeCheck( queryInfo.dataStart, queryInfo.dataLength,
350  objectSize ) );
351  contentListItem->payload = \
352  ( BYTE * ) contentListItem->object + queryInfo.dataStart;
353  contentListItem->payloadSize = queryInfo.dataLength;
354  }
355  if( queryInfo.version > envelopeInfoPtr->version )
356  envelopeInfoPtr->version = queryInfo.version;
357 
358  /* If we're completing the read of the data in a one-pass signature
359  packet, we're done */
360  if( isContinuedSignature )
361  return( CRYPT_OK );
362 
363  /* If it's signed data, create a hash action to process it. Because PGP
364  only applies one level of signing per packet nesting level we don't
365  have to worry that this will add redundant hash actions as there'll
366  only ever be one */
367  if( queryInfo.type == CRYPT_OBJECT_SIGNATURE )
368  {
369  MESSAGE_CREATEOBJECT_INFO createInfo;
370 
371  REQUIRES( moreActionsPossible( envelopeInfoPtr->actionList ) );
372 
373  /* Append a new hash action to the action list */
374  setMessageCreateObjectInfo( &createInfo,
375  contentListItem->clSigInfo.hashAlgo );
377  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
379  if( cryptStatusError( status ) )
380  {
381  deleteContentList( envelopeInfoPtr->memPoolState,
382  &contentListItem );
383  return( status );
384  }
385  status = addAction( &envelopeInfoPtr->actionList,
386  envelopeInfoPtr->memPoolState, ACTION_HASH,
387  createInfo.cryptHandle );
388  if( cryptStatusError( status ) )
389  {
390  krnlSendNotifier( createInfo.cryptHandle,
392  deleteContentList( envelopeInfoPtr->memPoolState,
393  &contentListItem );
394  return( status );
395  }
396  }
397  status = appendContentListItem( envelopeInfoPtr, contentListItem );
398  if( cryptStatusError( status ) )
399  {
400  deleteContentList( envelopeInfoPtr->memPoolState,
401  &contentListItem );
402  return( status );
403  }
404 
405  return( CRYPT_OK );
406  }
407 
408 /****************************************************************************
409 * *
410 * Header Processing Routines *
411 * *
412 ****************************************************************************/
413 
414 /* Process the header of a packet */
415 
416 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
417 static int processPacketHeader( INOUT ENVELOPE_INFO *envelopeInfoPtr,
418  INOUT STREAM *stream,
419  INOUT_ENUM( PGP_DEENVSTATE ) \
421  {
422  const int streamPos = stell( stream );
423  PGP_PACKET_TYPE packetType;
424  BOOLEAN isIndefinite;
425  long packetLength;
426  int value, status;
427 
428  assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
429  assert( isWritePtr( stream, sizeof( STREAM ) ) );
430  assert( isWritePtr( state, sizeof( PGP_DEENV_STATE ) ) );
431 
432  REQUIRES( sanityCheck( envelopeInfoPtr ) );
433  REQUIRES( streamPos >= 0 && streamPos < MAX_INTLENGTH );
434 
435  /* Read the PGP packet type and figure out what we've got. If we're at
436  the start of the data we allow noise packets like PGP_PACKET_MARKER
437  (with a length of 3), otherwise we only allow standard packets */
438  status = getPacketInfo( stream, envelopeInfoPtr, &packetType,
439  &packetLength, &isIndefinite,
440  ( *state == PGP_DEENVSTATE_NONE ) ? 3 : 8 );
441  if( cryptStatusError( status ) )
442  {
443  retExt( status,
444  ( status, ENVELOPE_ERRINFO,
445  "Invalid PGP packet header" ) );
446  }
447 
448  /* Process as much of the header as we can and move on to the next state.
449  Since PGP uses sequential discrete packets, if we encounter any of
450  the non-payload packet types we stay in the initial "none" state
451  because we don't know what's next */
452  switch( packetType )
453  {
454  case PGP_PACKET_DATA:
455  {
456  int length;
457 
458  /* Skip the content-type, filename, and date */
459  sSkip( stream, 1 );
460  status = length = sgetc( stream );
461  if( !cryptStatusError( status ) )
462  status = sSkip( stream, length + 4 );
463  if( cryptStatusError( status ) )
464  {
465  retExt( status,
466  ( status, ENVELOPE_ERRINFO,
467  "Invalid PGP data packet start" ) );
468  }
469 
470  /* Remember that this is a pure data packet, record the content
471  length (if we have the necessary information), and move on to
472  the payload */
473  envelopeInfoPtr->contentType = CRYPT_CONTENT_DATA;
474  if( !isIndefinite )
475  {
476  const long payloadSize = \
477  packetLength - ( 1 + 1 + length + 4 );
478  if( payloadSize < 1 || payloadSize > MAX_INTLENGTH )
479  return( CRYPT_ERROR_BADDATA );
480  envelopeInfoPtr->payloadSize = payloadSize;
481  }
482  *state = PGP_DEENVSTATE_DATA;
483  break;
484  }
485 
486  case PGP_PACKET_COPR:
487  if( envelopeInfoPtr->usage != ACTION_NONE )
488  return( CRYPT_ERROR_BADDATA );
489  envelopeInfoPtr->usage = ACTION_COMPRESS;
490 #ifdef USE_COMPRESSION
491  value = sgetc( stream );
492  if( cryptStatusError( value ) )
493  return( value );
494  switch( value )
495  {
496  case PGP_ALGO_ZIP:
497  /* PGP 2.x has a funny compression level based on DOS
498  memory limits (13-bit windows) and no zlib header
499  (because it uses very old InfoZIP code). Setting the
500  windowSize to a negative value has the undocumented
501  effect of not reading zlib headers */
502  if( inflateInit2( &envelopeInfoPtr->zStream, -13 ) != Z_OK )
503  return( CRYPT_ERROR_MEMORY );
504  break;
505 
506  case PGP_ALGO_ZLIB:
507  /* Standard zlib compression */
508  if( inflateInit( &envelopeInfoPtr->zStream ) != Z_OK )
509  return( CRYPT_ERROR_MEMORY );
510  break;
511 
512  default:
513  return( CRYPT_ERROR_NOTAVAIL );
514  }
515  envelopeInfoPtr->flags |= ENVELOPE_ZSTREAMINITED;
516  if( packetLength != CRYPT_UNUSED )
517  {
518  const long payloadSize = packetLength - 1;
519 
520  /* Most implementations use the PGP 2.x "keep going until
521  you run out of data" non-length encoding that's neither
522  a definite- nor an indefinite length, but it's possible
523  that something somewhere will use a proper definite
524  length so we accomodate this here */
525  if( payloadSize < 1 || payloadSize > MAX_INTLENGTH )
526  return( CRYPT_ERROR_BADDATA );
527  envelopeInfoPtr->payloadSize = payloadSize;
528  }
529  else
530  {
531  /* Remember that we have no length information available for
532  the payload */
533  envelopeInfoPtr->dataFlags |= ENVDATA_NOLENGTHINFO;
534  }
535  *state = PGP_DEENVSTATE_DATA;
536  break;
537 #else
538  return( CRYPT_ERROR_NOTAVAIL );
539 #endif /* USE_COMPRESSION */
540 
541  case PGP_PACKET_SKE:
542  case PGP_PACKET_PKE:
543  /* Read the SKE/PKE packet */
544  if( envelopeInfoPtr->usage != ACTION_NONE && \
545  envelopeInfoPtr->usage != ACTION_CRYPT )
546  return( CRYPT_ERROR_BADDATA );
547  envelopeInfoPtr->usage = ACTION_CRYPT;
548  sseek( stream, streamPos ); /* Reset to start of packet */
549  status = addContentListItem( envelopeInfoPtr, stream, FALSE );
550  if( cryptStatusError( status ) )
551  {
552  retExt( status,
553  ( status, ENVELOPE_ERRINFO,
554  "Invalid PGP %s packet",
555  ( packetType == PGP_PACKET_SKE ) ? "SKE" : "PKE" ) );
556  }
557  break;
558 
561  /* Try and guess whether this is a standalone signature. This
562  is rather difficult since unlike S/MIME there's no way to
563  tell whether a PGP signature packet is part of other data or
564  a standalone item. The best that we can do is assume that if
565  the caller added a hash action and we find a signature then
566  it's a detached signature. Unfortunately there's no way to
567  tell whether a signature packet with no user-supplied hash is
568  a standalone signature or the start of further signed data so
569  we can't handle detached signatures where the user doesn't
570  supply the hash */
571  if( envelopeInfoPtr->usage == ACTION_SIGN && \
572  envelopeInfoPtr->actionList != NULL && \
573  envelopeInfoPtr->actionList->action == ACTION_HASH )
574  {
575  /* We can't have a detached signature packet as a one-pass
576  signature */
577  if( packetType == PGP_PACKET_SIGNATURE_ONEPASS )
578  {
581  "PGP detached signature can't be a one-pass "
582  "signature packet" ) );
583  }
584  envelopeInfoPtr->flags |= ENVELOPE_DETACHED_SIG;
585  }
586 
587  /* Read the signature/signature information packet. We allow
588  the usage to be set already if we find a signature packet
589  since it could have been preceded by a one-pass signature
590  packet or be a detached signature */
591  if( envelopeInfoPtr->usage != ACTION_NONE && \
592  !( packetType == PGP_PACKET_SIGNATURE && \
593  envelopeInfoPtr->usage == ACTION_SIGN ) )
594  return( CRYPT_ERROR_BADDATA );
595  envelopeInfoPtr->usage = ACTION_SIGN;
596  sseek( stream, streamPos ); /* Reset to start of packet */
597  status = addContentListItem( envelopeInfoPtr, stream, FALSE );
598  if( cryptStatusError( status ) )
599  {
600  retExt( status,
601  ( status, ENVELOPE_ERRINFO,
602  "Invalid PGP %s signature packet",
603  ( packetType == PGP_PACKET_SIGNATURE_ONEPASS ) ? \
604  "one-pass" : "" ) );
605  }
606  if( envelopeInfoPtr->flags & ENVELOPE_DETACHED_SIG )
607  {
608  /* If it's a one-pass signature there's no payload present
609  so we can go straight to the postdata state */
610  envelopeInfoPtr->dataFlags |= ENVDATA_HASHACTIONSACTIVE;
611  envelopeInfoPtr->payloadSize = 0;
612  *state = PGP_DEENVSTATE_DONE;
613  }
614  else
615  *state = PGP_DEENVSTATE_DATA;
616  break;
617 
618  case PGP_PACKET_ENCR_MDC:
619  /* The encrypted-data-with-MDC packet is preceded by a version
620  number */
621  status = value = sgetc( stream );
622  if( !cryptStatusError( status ) && value != 1 )
623  status = CRYPT_ERROR_BADDATA;
624  if( !cryptStatusError( status ) )
625  {
626  /* Adjust the length for the version number and make sure
627  that what's left is valid. In theory this check isn't
628  necessary because getPacketInfo() has enforced a minimum
629  length, but we do it anyway just to be sure */
630  packetLength--;
631  if( packetLength <= 0 || packetLength > MAX_INTLENGTH )
632  status = CRYPT_ERROR_BADDATA;
633  }
634  if( cryptStatusError( status ) )
635  {
636  retExt( status,
637  ( status, ENVELOPE_ERRINFO,
638  "Invalid MDC packet header" ) );
639  }
640  /* Fall through */
641 
642  case PGP_PACKET_ENCR:
643  if( envelopeInfoPtr->usage != ACTION_NONE && \
644  envelopeInfoPtr->usage != ACTION_CRYPT )
645  return( CRYPT_ERROR_BADDATA );
646  if( !isIndefinite )
647  envelopeInfoPtr->payloadSize = packetLength;
648  envelopeInfoPtr->usage = ACTION_CRYPT;
649  *state = ( packetType == PGP_PACKET_ENCR_MDC ) ? \
651  break;
652 
653  case PGP_PACKET_MARKER:
654  /* Obsolete marker packet, skip it */
655  return( sSkip( stream, packetLength ) );
656 
657  default:
658  /* Unrecognised/invalid packet type */
661  "Unrecognised PGP packet type %d", packetType ) );
662  }
663 
664  ENSURES( sanityCheck( envelopeInfoPtr ) );
665 
666  return( CRYPT_OK );
667  }
668 
669 /* PGP doesn't provide any indication of what the content of the packet's
670  encrypted payload is so we have to burrow down into the encrypted data to
671  see whether the payload needs any further processing. To do this we look
672  ahead into the data to see whether we need to strip the header (for a
673  plain data packet) or inform the user that there's a nested content type.
674  This process is complicated by the fact that there are various ways of
675  representing the length information for both outer and inner packets and
676  the fact that the payload can consist of more than one packet, but we're
677  really only interested in the first one in most cases. The calculation
678  of the encapsulated payload length is as follows:
679 
680  +---+---+............................................
681  |len|hdr| : Encrypted data
682  +---+---+............................................
683  : :
684  +---+---+-------------------------------+---+
685  |len|hdr| Payload | ? | Inner content
686  +---+---+-------------------------------+---+
687 
688  Definite payload length:
689  Payload = (inner) length - (inner) hdr.
690 
691  Unknown length (only allowed for compressed data):
692  Payload = (leave as is since by definition the compressed data
693  extends to EOF).
694 
695  Indefinite payload length:
696  Payload = to EOC, handled by decode.c routines */
697 
698 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
699 static int processPacketDataHeader( INOUT ENVELOPE_INFO *envelopeInfoPtr,
700  OUT_ENUM_OPT( PGP_DEENVSTATE ) \
701  PGP_DEENV_STATE *state )
702  {
703  static const MAP_TABLE typeMapTbl[] = {
712  };
713  STREAM headerStream;
714  BYTE buffer[ 32 + 256 + 8 ]; /* Max.data packet header size */
715  PGP_PACKET_TYPE packetType;
716  long packetLength;
717  int value, length, status;
718 
719  assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
720  assert( isWritePtr( state, sizeof( PGP_DEENV_STATE ) ) );
721 
722  REQUIRES( sanityCheck( envelopeInfoPtr ) );
723  REQUIRES( envelopeInfoPtr->oobDataLeft < 32 + 256 );
724 
725  /* If we're down to stripping raw header data, remove it from the buffer
726  and exit */
727  if( envelopeInfoPtr->oobEventCount <= 0 )
728  {
729  status = envelopeInfoPtr->copyFromEnvelopeFunction( envelopeInfoPtr,
730  buffer, envelopeInfoPtr->oobDataLeft,
731  &length, ENVCOPY_FLAG_NONE );
732  if( cryptStatusError( status ) )
733  return( status );
734  if( length < envelopeInfoPtr->oobDataLeft )
735  return( CRYPT_ERROR_UNDERFLOW );
736 
737  /* We've successfully stripped all of the out-of-band data, clear the
738  data counter. If it's compressed data (which doesn't have a 1:1
739  correspondence between input and output and which has an unknown-
740  length encoding so there's no length information to adjust),
741  exit */
742  envelopeInfoPtr->oobDataLeft = 0;
743  if( envelopeInfoPtr->usage == ACTION_COMPRESS )
744  {
745  *state = PGP_DEENVSTATE_DONE;
746 
747  ENSURES( sanityCheck( envelopeInfoPtr ) );
748 
749  return( CRYPT_OK );
750  }
751 
752  /* Adjust the current data count by what we've removed. The reason
753  we have to do this is because segmentSize records the amount of
754  data copied in (rather than out, as we've done here) but since it
755  was copied directly into the envelope buffer as part of the
756  header-processing rather than via copyToDeenvelope() (which is
757  what usually adjusts segmentSize for us) we have to manually
758  adjust the value here */
759  if( envelopeInfoPtr->segmentSize > 0 )
760  {
761  envelopeInfoPtr->segmentSize -= length;
762  ENSURES( envelopeInfoPtr->segmentSize >= 0 && \
763  envelopeInfoPtr->segmentSize < MAX_INTLENGTH );
764 
765  /* If we've reached the end of the data (i.e. the entire current
766  segment is contained within the data present in the buffer)
767  remember that what's left still needs to be processed (e.g.
768  hashed in the case of signed data) on the way out */
769  if( envelopeInfoPtr->segmentSize <= envelopeInfoPtr->bufPos )
770  {
771  envelopeInfoPtr->dataLeft = envelopeInfoPtr->segmentSize;
772  envelopeInfoPtr->segmentSize = 0;
773  }
774  }
775 
776  /* We've processed the header, if this is signed data we start
777  hashing from this point (the PGP RFCs are wrong in this regard,
778  only the payload is hashed and not the entire packet) */
779  if( envelopeInfoPtr->usage == ACTION_SIGN )
780  envelopeInfoPtr->dataFlags |= ENVDATA_HASHACTIONSACTIVE;
781 
782  /* We're done */
783  *state = PGP_DEENVSTATE_DONE;
784 
785  ENSURES( sanityCheck( envelopeInfoPtr ) );
786  return( CRYPT_OK );
787  }
788 
789  /* We have to perform all sorts of special-case processing to handle the
790  out-of-band packet header at the start of the payload. Initially, we
791  need to find out how much header data is actually present. The header
792  for a plain data packet consists of:
793 
794  byte ctb
795  byte[] length
796  byte type = 'b' | 't'
797  byte filename length
798  byte[] filename
799  byte[4] timestamp
800 
801  The smallest size for this header (1-byte length, no filename) is
802  1 + 1 + 1 + 1 + 4 = 8 bytes. This is also just enough to get us to
803  the filename length for a maximum-size header, which is 1 + 5 + 1 + 1
804  bytes up to the filename length and covers the type + length range
805  of every other packet type, which can be from 1 to 1 + 5 bytes. Thus
806  we read 8 bytes, setting the OOB data flag to indicate that this is a
807  read-ahead read that doesn't remove data from the buffer */
808  status = envelopeInfoPtr->copyFromEnvelopeFunction( envelopeInfoPtr,
809  buffer, 8, &length,
811  if( cryptStatusError( status ) )
812  return( status );
813  if( length < 8 )
814  return( CRYPT_ERROR_UNDERFLOW );
815 
816  /* Read the header information and see what we've got */
817  sMemConnect( &headerStream, buffer, length );
818  status = getPacketInfo( &headerStream, envelopeInfoPtr, &packetType,
819  &packetLength, NULL, 8 );
820  if( cryptStatusError( status ) )
821  {
822  sMemDisconnect( &headerStream );
823  return( status );
824  }
825 
826  /* Remember the total data packet size unless it's compressed data,
827  which doesn't have a 1:1 correspondence between input and output */
828  if( envelopeInfoPtr->usage != ACTION_COMPRESS )
829  {
830 /******/
831 /* All of this only for definite-length packets or indefinite + EOC-seen */
832 /******/
833  /* If it's a definite-length packet, use the overall packet size.
834  This also skips any MDC packets that may be attached to the end
835  of the plaintext */
836  if( packetLength != CRYPT_UNUSED )
837  {
838  envelopeInfoPtr->segmentSize = stell( &headerStream ) + \
839  packetLength;
840 
841  /* If we're using the definite-length encoding (which is the
842  default for PGP) then the overall payload size is equal to
843  the segment size */
844  if( envelopeInfoPtr->dataFlags & ENVDATA_NOSEGMENT )
845  envelopeInfoPtr->payloadSize = envelopeInfoPtr->segmentSize;
846  }
847  else
848  {
849  ENSURES( packetType == PGP_PACKET_COPR );
850  ENSURES( envelopeInfoPtr->payloadSize != CRYPT_UNUSED );
851 
852  /* It's an arbitrary-length compressed data packet, use the
853  length that we got earlier from the outer packet */
854  if( envelopeInfoPtr->dataFlags & ENVDATA_ENDOFCONTENTS )
855  {
856 /******/
857 /* What happens in this case? */
858 /******/
859  DEBUG_DIAG(( "Found EOC for unknown-length compressed "
860  "data" ));
861  assert( DEBUG_WARN );
862  }
863  else
864  {
865  envelopeInfoPtr->segmentSize = envelopeInfoPtr->payloadSize;
866 
867  /* If we've reached the end of the data (i.e. the entire
868  current segment is contained within the data present in
869  the buffer) remember that what's left still needs to be
870  processed (e.g. hashed in the case of signed data) on the
871  way out */
872  if( envelopeInfoPtr->segmentSize <= envelopeInfoPtr->bufPos )
873  {
874  envelopeInfoPtr->dataLeft = envelopeInfoPtr->segmentSize;
875  envelopeInfoPtr->segmentSize = 0;
876  }
877  }
878  }
879  }
880 
881  /* If it's a literal data packet, parse it so that we can strip it from
882  the data that we return to the caller. We know that the reads can't
883  fail because the readahead read has confirmed that there are at least
884  8 bytes available, but we check anyway just to be sure */
885  if( packetType == PGP_PACKET_DATA )
886  {
887  int extraLen;
888 
889  ( void ) sgetc( &headerStream ); /* Skip content type */
890  status = extraLen = sgetc( &headerStream );
891  if( !cryptStatusError( status ) )
892  {
893  envelopeInfoPtr->oobDataLeft = stell( &headerStream ) + \
894  extraLen + 4;
895  }
896  sMemDisconnect( &headerStream );
897  if( cryptStatusError( status ) )
898  return( status );
899 
900  /* Remember that this is a pure data packet */
901  envelopeInfoPtr->contentType = CRYPT_CONTENT_DATA;
902 
903  /* We've processed enough of the header to know what to do next,
904  move on to the next sub-state where we just consume all of the
905  input. This has to be done as a sub-state within the
906  PGP_DEENVSTATE_DATA_HEADER state since we can encounter a
907  (recoverable) error between reading the out-of-band data header
908  and reading the out-of-band data itself */
909  envelopeInfoPtr->oobEventCount--;
910 
911  ENSURES( sanityCheck( envelopeInfoPtr ) );
912 
913  return( CRYPT_OK );
914  }
915 
916  sMemDisconnect( &headerStream );
917 
918  /* If it's a known packet type, indicate it as the nested content type */
919  status = mapValue( packetType, &value, typeMapTbl,
920  FAILSAFE_ARRAYSIZE( typeMapTbl, MAP_TABLE ) );
921  if( cryptStatusError( status ) )
922  return( CRYPT_ERROR_BADDATA );
923  envelopeInfoPtr->contentType = value;
924 
925 #if 0 /* 12/4/06 See previous comment */
926  /* If it's not compressed data (which doesn't have a 1:1 correspondence
927  between input and output) and we've reached the end of the data (i.e.
928  the entire current segment is contained within the data present in
929  the buffer), remember that what's left still needs to be processed
930  (e.g. hashed in the case of signed data) on the way out */
931  if( envelopeInfoPtr->usage != ACTION_COMPRESS && \
932  envelopeInfoPtr->segmentSize <= envelopeInfoPtr->bufPos )
933  {
934  envelopeInfoPtr->dataLeft = envelopeInfoPtr->segmentSize;
935  envelopeInfoPtr->segmentSize = 0;
936  }
937 #endif /* 0 */
938 
939  /* Don't try and process the content any further */
940  envelopeInfoPtr->oobEventCount = envelopeInfoPtr->oobDataLeft = 0;
941  *state = PGP_DEENVSTATE_DONE;
942 
943  ENSURES( sanityCheck( envelopeInfoPtr ) );
944 
945  return( CRYPT_OK );
946  }
947 
948 /* Process the start of an encrypted data packet */
949 
950 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
951 static int processEncryptedPacket( INOUT ENVELOPE_INFO *envelopeInfoPtr,
952  INOUT STREAM *stream,
953  IN_ENUM( PGP_DEENVSTATE ) \
954  const PGP_DEENV_STATE state )
955  {
956  BYTE ivInfoBuffer[ CRYPT_MAX_IVSIZE + 2 + 8 ];
957  int ivSize, offset, status;
958 
959  assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
960  assert( isWritePtr( stream, sizeof( STREAM ) ) );
961 
962  REQUIRES( sanityCheck( envelopeInfoPtr ) );
963  REQUIRES( state > PGP_DEENVSTATE_NONE && state < PGP_DEENVSTATE_LAST );
964 
965  /* If there aren't any non-session-key keying resource objects present
966  then we can't go any further until we get a session key */
967  if( envelopeInfoPtr->actionList == NULL )
968  {
969  /* There's no session key object present, add a pseudo-object that
970  takes the place of the (password-derived) session key object in
971  the content list. This can only occur for PGP 2.x conventionally-
972  encrypted data, which didn't encode any algorithm information
973  with the data, so if we get to this point we know that we've hit
974  data encrypted with the default IDEA/CFB encryption algorithm
975  derived from a user password using the default MD5 hash
976  algorithm */
977  if( envelopeInfoPtr->contentList == NULL )
978  {
979  status = addContentListItem( envelopeInfoPtr, NULL, FALSE );
980  if( cryptStatusError( status ) )
981  return( status );
982  }
983 
984  /* We can't continue until we're given some sort of keying resource */
985  return( CRYPT_ENVELOPE_RESOURCE );
986  }
987  ENSURES( envelopeInfoPtr->actionList != NULL && \
988  envelopeInfoPtr->actionList->action == ACTION_CRYPT );
989 
990  /* Read and process PGP's peculiar two-stage IV */
991  status = krnlSendMessage( envelopeInfoPtr->actionList->iCryptHandle,
992  IMESSAGE_GETATTRIBUTE, &ivSize,
994  if( cryptStatusOK( status ) )
995  status = sread( stream, ivInfoBuffer, ivSize + 2 );
996  if( !cryptStatusError( status ) )
997  {
998  status = pgpProcessIV( envelopeInfoPtr->actionList->iCryptHandle,
999  ivInfoBuffer, ivSize + 2, ivSize, FALSE,
1000  ( state == PGP_DEENVSTATE_ENCR ) ? \
1001  TRUE : FALSE );
1002  }
1003  if( cryptStatusError( status ) )
1004  return( status );
1005  envelopeInfoPtr->iCryptContext = \
1006  envelopeInfoPtr->actionList->iCryptHandle;
1007 #if 0 /************************************************/
1008 { /* For buggy McAfee PGP with indefinite lengths */
1009 BYTE buffer[ 1024 ], *srcPtr = sMemBufPtr( stream );
1010 
1011 memcpy( buffer, srcPtr - 14, 32 );
1012 krnlSendMessage( envelopeInfoPtr->iCryptContext, IMESSAGE_CTX_DECRYPT,
1013  buffer, 32 );
1014 } /* For buggy McAfee PGP with indefinite lengths */
1015 #endif /************************************************/
1016 
1017  /* If we're keeping track of the outer packet size in case there's no
1018  inner size info present, adjust it by the data that we've just
1019  processed and any other data that may be present */
1020  offset = stell( stream );
1021  if( state == PGP_DEENVSTATE_ENCR_MDC )
1022  {
1023  /* If we're using a definite-length encoding, adjust the total data
1024  length for the length of the tacked-on MDC packet */
1025  if( envelopeInfoPtr->dataFlags & ENVDATA_NOSEGMENT )
1026  {
1027  /* There was a bug in all versions of GPG before 1.0.8, which
1028  omitted the MDC packet length when a packet was encrypted
1029  without compression. As a result uncompressed messages
1030  generated by these versions can't be processed */
1031  offset += PGP_MDC_PACKET_SIZE;
1032  }
1033  else
1034  {
1035  /* We're using an indefinite-length encoding, remember that we
1036  have to adjust for the tacked-on MDC packet when we hit the
1037  last data segment */
1038  envelopeInfoPtr->dataFlags |= ENVDATA_HASATTACHEDOOB;
1039  }
1040  }
1041 /******/
1042 /* Is the IV part of the length? If so how to handle with indefinite lengths? */
1043 /* (offset = IV size + optional MDC size, i.e. we adjust the length based on the */
1044 /* IV bytes read) */
1045 /******/
1046  if( envelopeInfoPtr->payloadSize != CRYPT_UNUSED )
1047  envelopeInfoPtr->payloadSize -= offset;
1048 
1049  /* If there's an MDC packet present, prepare to hash the payload data */
1050  if( state == PGP_DEENVSTATE_ENCR_MDC )
1051  {
1052  MESSAGE_CREATEOBJECT_INFO createInfo;
1053 
1054  REQUIRES( moreActionsPossible( envelopeInfoPtr->actionList ) );
1055 
1056  /* Append a hash action to the action list */
1060  &createInfo, OBJECT_TYPE_CONTEXT );
1061  if( cryptStatusError( status ) )
1062  return( status );
1063  status = addAction( &envelopeInfoPtr->actionList,
1064  envelopeInfoPtr->memPoolState, ACTION_HASH,
1065  createInfo.cryptHandle );
1066  if( cryptStatusError( status ) )
1067  {
1068  krnlSendNotifier( createInfo.cryptHandle,
1070  return( status );
1071  }
1072  envelopeInfoPtr->dataFlags |= ENVDATA_HASHACTIONSACTIVE;
1073  }
1074 
1075  ENSURES( sanityCheck( envelopeInfoPtr ) );
1076 
1077  return( CRYPT_OK );
1078  }
1079 
1080 /****************************************************************************
1081 * *
1082 * Trailer Processing Routines *
1083 * *
1084 ****************************************************************************/
1085 
1086 /* Process an MDC packet */
1087 
1088 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
1089 static int processMDC( INOUT ENVELOPE_INFO *envelopeInfoPtr )
1090  {
1091  int status;
1092 
1093  assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
1094 
1095  REQUIRES( sanityCheck( envelopeInfoPtr ) );
1096 
1097  /* Make sure that there's enough data left in the stream to obtain the
1098  MDC info */
1099  if( envelopeInfoPtr->bufPos - \
1100  envelopeInfoPtr->dataLeft < PGP_MDC_PACKET_SIZE )
1101  return( CRYPT_ERROR_UNDERFLOW );
1102 
1103  /* Processing beyond this point gets rather complex because we have to
1104  defer reading the MDC packet until all of the remaining data has been
1105  popped, while processing reaches this point when data is pushed.
1106  Conventionally signed/hashed data hashes the plaintext so once we
1107  reach this point we can wrap up the hashing ready for the (user-
1108  initiated) signature check. The MDC packet however is still
1109  encrypted at this point, along with some or all of the data to be
1110  hashed, which means that we can't do anything yet:
1111 
1112  <-- Decr. -><- Encrypted ->
1113  --------+-------------+---------
1114  .... |///////| MDC | ....
1115  --------+-------------+---------
1116  ^ ^
1117  bufPos bufEnd
1118 
1119  In order to handle this special-case situation we'd have to add extra
1120  capabilities to the data-popping code to tell it that after a certain
1121  amount of data has been popped what's still left is MDC data. This
1122  severely screws up the layering because the functionality required is
1123  neither at the cryptenv.c level nor at the decode.c level, and
1124  represents an approach that was abandoned in cryptlib 2.1 when it
1125  proved impossible to get it working reliably under all circumstances
1126  (it's provably impossible to do with the ASN.1 variable-length length
1127  encoding where changing data by one byte can result in a variable
1128  change of length for inner lengths. This makes it impossible to
1129  encode some data lengths to the fixed size required by a CBC-mode
1130  cipher, and OpenPGP's more recent variable-lengths are no better).
1131  This is why cryptlib uses separate passes for each processing layer
1132  rather than trying to combine encryption and signing into a single
1133  pass.
1134 
1135  Because of this, handling of MDC packets is only done if all of the
1136  data in the envelope has been popped (but see the note below), fully
1137  general handling won't be added unless there is sufficient user
1138  demand to justify messing up the architectural layering of the
1139  enveloping code. Note that this situation can never occur since
1140  we're being called when data is pushed, the following code is present
1141  only as a representative example */
1142  if( envelopeInfoPtr->dataLeft == PGP_MDC_PACKET_SIZE )
1143  {
1144  BYTE buffer[ PGP_MDC_PACKET_SIZE + 8 ];
1145  int length;
1146 
1147  DEBUG_DIAG(( "Processing MDC data at end of packet" ));
1148  assert( DEBUG_WARN );
1149 
1150  status = envelopeInfoPtr->copyFromEnvelopeFunction( envelopeInfoPtr,
1151  buffer, PGP_MDC_PACKET_SIZE, &length,
1153  if( cryptStatusError( status ) )
1154  return( status );
1155  if( length < PGP_MDC_PACKET_SIZE || \
1156  buffer[ 0 ] != 0xD0 || buffer[ 1 ] != 0x14 )
1157  return( CRYPT_ERROR_BADDATA );
1158 
1159  /* Hash the trailer bytes (the start of the MDC packet) and wrap up
1160  the hashing */
1161  status = envelopeInfoPtr->processExtraData( envelopeInfoPtr,
1162  buffer + 2,
1163  PGP_MDC_PACKET_SIZE - 2 );
1164  if( cryptStatusOK( status ) )
1165  status = envelopeInfoPtr->processExtraData( envelopeInfoPtr,
1166  "", 0 );
1167  if( cryptStatusError( status ) )
1168  return( status );
1169  }
1170 
1171  ENSURES( sanityCheck( envelopeInfoPtr ) );
1172 
1173  return( CRYPT_OK );
1174  }
1175 
1176 /****************************************************************************
1177 * *
1178 * Process Envelope Preamble/Postamble *
1179 * *
1180 ****************************************************************************/
1181 
1182 /* Process the non-data portions of a PGP message. This is a complex event-
1183  driven state machine, but instead of reading along a (hypothetical
1184  Turing-machine) tape someone has taken the tape and cut it into bits and
1185  keeps feeding them to us and saying "See what you can do with this" (and
1186  occasionally "Where's the bloody spoons?"). Since PGP uses sequential
1187  discrete packets rather than the nested objects encountered in the ASN.1-
1188  encoded data format the parsing code is made slightly simpler because
1189  (for example) the PKC info is just an unconnected sequence of packets
1190  rather than a SEQUENCE or SET OF as for cryptlib and PKCS #7/CMS. OTOH
1191  since there's no indication of what's next we have to perform a complex
1192  lookahead to see what actions we have to take once we get to the payload.
1193  The end result is that teh code is actually vastly more complex than the
1194  CMS equivalent */
1195 
1196 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
1197 static int processPreamble( INOUT ENVELOPE_INFO *envelopeInfoPtr )
1198  {
1199  PGP_DEENV_STATE state = envelopeInfoPtr->pgpDeenvState;
1200  STREAM stream;
1201  int remainder, streamPos = 0, iterationCount, status = CRYPT_OK;
1202 
1203  assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
1204 
1205  REQUIRES( sanityCheck( envelopeInfoPtr ) );
1206 
1207  /* If we've finished processing the start of the message, header, don't
1208  do anything */
1209  if( state == PGP_DEENVSTATE_DONE )
1210  return( CRYPT_OK );
1211 
1212  sMemConnect( &stream, envelopeInfoPtr->buffer, envelopeInfoPtr->bufPos );
1213 
1214  /* Keep consuming information until we run out of input or reach the
1215  plaintext data packet */
1216  for( iterationCount = 0;
1217  state != PGP_DEENVSTATE_DONE && iterationCount < FAILSAFE_ITERATIONS_MED;
1218  iterationCount++ )
1219  {
1220  /* Read the PGP packet type and figure out what we've got */
1221  if( state == PGP_DEENVSTATE_NONE )
1222  {
1223  status = processPacketHeader( envelopeInfoPtr, &stream, &state );
1224  if( cryptStatusError( status ) )
1225  break;
1226 
1227  /* Remember how far we got */
1228  streamPos = stell( &stream );
1229  }
1230 
1231  /* Process the start of an encrypted data packet */
1232  if( state == PGP_DEENVSTATE_ENCR || \
1233  state == PGP_DEENVSTATE_ENCR_MDC )
1234  {
1235  status = processEncryptedPacket( envelopeInfoPtr, &stream, state );
1236  if( cryptStatusError( status ) )
1237  {
1238  /* If it's a resource-needed status then it's not an
1239  error */
1240  if( status == CRYPT_ENVELOPE_RESOURCE )
1241  break;
1242 
1243  /* We may get non-data-related errors like
1244  CRYPT_ERROR_WRONGKEY so we only set extended error
1245  information if it's a data-related error */
1246  if( isDataError( status ) )
1247  {
1249  "Invalid PGP encrypted data packet header",
1250  40 );
1251  }
1252  break;
1253  }
1254 
1255  /* Remember where we are and move on to the next state */
1256  streamPos = stell( &stream );
1257  state = PGP_DEENVSTATE_DATA;
1258  }
1259 
1260  /* Process the start of a data packet */
1261  if( state == PGP_DEENVSTATE_DATA )
1262  {
1263  const int originalDataFlags = envelopeInfoPtr->dataFlags;
1264 
1265  /* Synchronise the data stream processing to the start of the
1266  encapsulated data. This is made somewhat complex by PGP's
1267  awkward packet format (see the comment for
1268  processPacketDataHeader()) which, unlike CMS:
1269 
1270  [ Hdr [ Encaps [ Octet String ] ] ]
1271 
1272  has:
1273  [ Hdr | Octet String ]
1274  [ Keyex ][ Hdr | Octet String ]
1275  [ Onepass ][ Hdr | Octet String ][ Signature ]
1276  [ Copr ][ Hdr | Octet String ]
1277 
1278  This means that if we're not processing a data packet then
1279  the content isn't the payload but a futher set of discrete
1280  packets that we don't want to touch. To work around this we
1281  temporarily set the ENVDATA_NOLENGTHINFO flag to indicate
1282  that it's a blob to be processed as an opaque unit, at the
1283  same time temporarily clearing any other flags that might
1284  mess up the opaque-blob handling */
1285  if( envelopeInfoPtr->usage != ACTION_NONE )
1286  envelopeInfoPtr->dataFlags = ENVDATA_NOLENGTHINFO;
1287  status = envelopeInfoPtr->syncDeenvelopeData( envelopeInfoPtr,
1288  &stream );
1289  envelopeInfoPtr->dataFlags = originalDataFlags;
1290  if( cryptStatusError( status ) )
1291  {
1293  "Couldn't synchronise envelope state prior "
1294  "to data payload processing", 68 );
1295  break;
1296  }
1297  streamPos = 0;
1298 
1299  /* Move on to the next state. For plain data we're done,
1300  however for other content types we have to either process or
1301  strip out the junk that PGP puts at the start of the
1302  content */
1303  if( envelopeInfoPtr->usage != ACTION_NONE )
1304  {
1305  envelopeInfoPtr->oobEventCount = 1;
1307  }
1308  else
1309  state = PGP_DEENVSTATE_DONE;
1310 
1311  ENSURES( checkActions( envelopeInfoPtr ) );
1312  }
1313 
1314  /* Burrow down into the encapsulated data to see what's next */
1315  if( state == PGP_DEENVSTATE_DATA_HEADER )
1316  {
1317  /* If there's no out-of-band data left to remove at the start of
1318  the payload, we're done. This out-of-band data handling
1319  sometimes requires two passes, the first time through
1320  oobEventCount is nonzero because it's been set in the
1321  preceding PGP_DEENVSTATE_DATA state and we fall through to
1322  processPacketDataHeader() which decrements the oobEventCount
1323  to zero. However processPacketDataHeader() may need to read
1324  out-of-band data in which case on the second time around
1325  oobDataLeft will be nonzero, resulting in a second call to
1326  processPacketDataHeader() to clear the remaining out-of-band
1327  data */
1328  if( envelopeInfoPtr->oobEventCount <= 0 && \
1329  envelopeInfoPtr->oobDataLeft <= 0 )
1330  {
1331  state = PGP_DEENVSTATE_DONE;
1332  break;
1333  }
1334 
1335  /* Process the encapsulated data header */
1336  status = processPacketDataHeader( envelopeInfoPtr, &state );
1337  if( cryptStatusError( status ) )
1338  {
1340  "Invalid PGP encapsulated content header",
1341  39 );
1342  break;
1343  }
1344  }
1345  }
1346  sMemDisconnect( &stream );
1347  if( iterationCount >= FAILSAFE_ITERATIONS_MED )
1348  {
1349  /* Technically this would be an overflow but that's a recoverable
1350  error so we make it a BADDATA, which is really what it is */
1351  return( CRYPT_ERROR_BADDATA );
1352  }
1353  envelopeInfoPtr->pgpDeenvState = state;
1354 
1355  ENSURES( streamPos >= 0 && streamPos < MAX_INTLENGTH && \
1356  envelopeInfoPtr->bufPos - streamPos >= 0 );
1357 
1358  /* Consume the input that we've processed so far by moving everything
1359  past the current position down to the start of the envelope buffer */
1360  remainder = envelopeInfoPtr->bufPos - streamPos;
1361  REQUIRES( remainder >= 0 && remainder < MAX_INTLENGTH && \
1362  streamPos + remainder <= envelopeInfoPtr->bufSize );
1363  if( remainder > 0 && streamPos > 0 )
1364  {
1365  REQUIRES( rangeCheck( streamPos, remainder,
1366  envelopeInfoPtr->bufSize ) );
1367  memmove( envelopeInfoPtr->buffer, envelopeInfoPtr->buffer + streamPos,
1368  remainder );
1369  }
1370  envelopeInfoPtr->bufPos = remainder;
1371  ENSURES( sanityCheck( envelopeInfoPtr ) );
1372  if( cryptStatusError( status ) )
1373  return( status );
1374 
1375  /* If all went OK but we're still not out of the header information,
1376  return an underflow error */
1377  return( ( state != PGP_DEENVSTATE_DONE ) ? \
1379  }
1380 
1381 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
1382 static int processPostamble( INOUT ENVELOPE_INFO *envelopeInfoPtr,
1383  STDC_UNUSED const BOOLEAN dummy )
1384  {
1385  CONTENT_LIST *contentListPtr;
1386  const BOOLEAN hasMDC = \
1387  ( envelopeInfoPtr->usage == ACTION_CRYPT && \
1388  ( envelopeInfoPtr->dataFlags & ENVDATA_HASHACTIONSACTIVE ) ) ? \
1389  TRUE : FALSE;
1390  int iterationCount, status = CRYPT_OK;
1391 
1392  assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
1393 
1394  REQUIRES( sanityCheck( envelopeInfoPtr ) );
1395 
1396  /* If that's all there is, return */
1397  if( envelopeInfoPtr->usage != ACTION_SIGN && !hasMDC )
1398  return( CRYPT_OK );
1399 
1400  /* If there's an MDC packet present complete the hashing and make sure
1401  that the integrity check matches */
1402  if( hasMDC )
1403  {
1404  status = processMDC( envelopeInfoPtr );
1405  if( cryptStatusError( status ) )
1406  {
1407  retExt( status,
1408  ( status, ENVELOPE_ERRINFO,
1409  "Invalid MDC packet data" ) );
1410  }
1411 
1412  return( CRYPT_OK );
1413  }
1414 
1415  /* Find the signature information in the content list. In theory this
1416  could get ugly because there could be multiple one-pass signature
1417  packets present but PGP handles multiple signatures by nesting them
1418  so this isn't a problem */
1419  for( contentListPtr = envelopeInfoPtr->contentList, iterationCount = 0;
1420  contentListPtr != NULL && \
1421  contentListPtr->envInfo != CRYPT_ENVINFO_SIGNATURE && \
1422  iterationCount < FAILSAFE_ITERATIONS_MED;
1423  contentListPtr = contentListPtr->next, iterationCount++ );
1424  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
1425  ENSURES( contentListPtr != NULL );
1426 
1427  /* PGP 2.x prepended (!!) signatures to the signed data, OpenPGP fixed
1428  this by splitting the signature into a header with signature info and
1429  a trailer with the actual signature. If we're processing a PGP 2.x
1430  signature we'll already have the signature data present so we only
1431  check for signature data if it's not already available */
1432  if( contentListPtr->object == NULL )
1433  {
1434  STREAM stream;
1435  long packetLength;
1436  PGP_PACKET_TYPE packetType;
1437 
1438  /* Make sure that there's enough data left in the stream to do
1439  something with. We require a minimum of 44 bytes, the size
1440  of the DSA signature payload, in the stream */
1441  if( envelopeInfoPtr->bufPos - \
1442  envelopeInfoPtr->dataLeft < PGP_MAX_HEADER_SIZE + 44 )
1443  return( CRYPT_ERROR_UNDERFLOW );
1444 
1445  REQUIRES( moreContentItemsPossible( envelopeInfoPtr->contentList ) );
1446 
1447  /* Read the signature packet at the end of the payload */
1448  sMemConnect( &stream, envelopeInfoPtr->buffer + envelopeInfoPtr->dataLeft,
1449  envelopeInfoPtr->bufPos - envelopeInfoPtr->dataLeft );
1450  status = getPacketInfo( &stream, envelopeInfoPtr, &packetType,
1451  &packetLength, NULL, 8 );
1452  if( cryptStatusOK( status ) && packetType != PGP_PACKET_SIGNATURE )
1453  status = CRYPT_ERROR_BADDATA;
1454  if( cryptStatusError( status ) )
1455  {
1456  sMemDisconnect( &stream );
1457  retExt( status,
1458  ( status, ENVELOPE_ERRINFO,
1459  "Invalid PGP signature packet header" ) );
1460  }
1461  sseek( &stream, 0 );
1462  status = addContentListItem( envelopeInfoPtr, &stream, TRUE );
1463  sMemDisconnect( &stream );
1464  if( cryptStatusError( status ) )
1465  {
1466  retExt( status,
1467  ( status, ENVELOPE_ERRINFO,
1468  "Invalid PGP signature packet" ) );
1469  }
1470  }
1471 
1472  /* When we reach this point there may still be unhashed data left in the
1473  buffer (it won't have been hashed yet because the hashing is performed
1474  when the data is copied out, after unwrapping and whatnot) so we hash
1475  it before we exit. Since we don't wrap up the hashing as we do with
1476  any other format (PGP hashes in all sorts of odds and ends after
1477  hashing the message body) we have to manually turn off hashing here */
1478  if( envelopeInfoPtr->dataLeft > 0 )
1479  {
1480  status = envelopeInfoPtr->processExtraData( envelopeInfoPtr,
1481  envelopeInfoPtr->buffer, envelopeInfoPtr->dataLeft );
1482  }
1483  envelopeInfoPtr->dataFlags &= ~ENVDATA_HASHACTIONSACTIVE;
1484  if( cryptStatusError( status ) )
1485  return( status );
1486 
1487  ENSURES( sanityCheck( envelopeInfoPtr ) );
1488 
1489  return( CRYPT_OK );
1490  }
1491 
1492 /****************************************************************************
1493 * *
1494 * Envelope Access Routines *
1495 * *
1496 ****************************************************************************/
1497 
1498 STDC_NONNULL_ARG( ( 1 ) ) \
1499 void initPGPDeenveloping( INOUT ENVELOPE_INFO *envelopeInfoPtr )
1500  {
1501  assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
1502 
1503  REQUIRES_V( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE );
1504 
1505  /* Set the access method pointers */
1506  envelopeInfoPtr->processPreambleFunction = processPreamble;
1507  envelopeInfoPtr->processPostambleFunction = processPostamble;
1508  envelopeInfoPtr->checkAlgo = pgpCheckAlgo;
1509 
1510  /* Set up the processing state information */
1511  envelopeInfoPtr->pgpDeenvState = PGP_DEENVSTATE_NONE;
1512 
1513  /* Turn off segmentation of the envelope payload. PGP has a single
1514  length at the start of the data and doesn't segment the payload */
1515  envelopeInfoPtr->dataFlags |= ENVDATA_NOSEGMENT;
1516  }
1517 #endif /* USE_PGP */