cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
pgp_rd.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib PGP Key Read Routines *
4 * Copyright Peter Gutmann 1992-2007 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "misc_rw.h"
11  #include "pgp_rw.h"
12  #include "keyset.h"
13  #include "pgp_key.h"
14 #else
15  #include "crypt.h"
16  #include "enc_dec/misc_rw.h"
17  #include "enc_dec/pgp_rw.h"
18  #include "keyset/keyset.h"
19  #include "keyset/pgp_key.h"
20 #endif /* Compiler-specific includes */
21 
22 #ifdef USE_PGPKEYS
23 
24 /****************************************************************************
25 * *
26 * Utility Routines *
27 * *
28 ****************************************************************************/
29 
30 /* Get the size of an encoded MPI and skip the payload data */
31 
32 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
33 static int getMPIsize( INOUT STREAM *stream,
34  IN_LENGTH_PKC const int minMpiSize,
35  IN_LENGTH_PKC const int maxMpiSize,
37  {
38  const long position = stell( stream );
39  int dummy, status;
40 
41  assert( isWritePtr( stream, sizeof( STREAM ) ) );
42  assert( isWritePtr( length, sizeof( int ) ) );
43 
44  REQUIRES( minMpiSize > 0 && minMpiSize <= CRYPT_MAX_PKCSIZE );
45  REQUIRES( maxMpiSize > 0 && maxMpiSize >= minMpiSize && \
46  maxMpiSize <= CRYPT_MAX_PKCSIZE );
47 
48  /* Clear return value */
49  *length = 0;
50 
51  status = readInteger16Ubits( stream, NULL, &dummy, minMpiSize,
52  maxMpiSize );
53  if( cryptStatusError( status ) )
54  return( status );
55  *length = ( int ) stell( stream ) - position;
56 
57  return( CRYPT_OK );
58  }
59 
60 /* Determine the minimum allowed packet size for a given packet type. The
61  minimum-length packet that we can encounter is a single-byte trust
62  packet, then two bytes for a userID, and three bytes for a marker
63  packet. Other than that all packets must be at least eight bytes in
64  length */
65 
66 CHECK_RETVAL_RANGE( 0, 8 ) \
67 static int getMinPacketSize( IN_BYTE const int packetType )
68  {
69  ENSURES_EXT( ( packetType >= 0 && \
70  packetType <= 0xFF ), 0 );
71  /* This could be any packet type including new values not
72  covered by the PGP_PACKET_TYPE range so we can't be too
73  picky about values */
74 
75  return( ( packetType == PGP_PACKET_TRUST ) ? 1 : \
76  ( packetType == PGP_PACKET_USERID ) ? 2 : \
77  ( packetType == PGP_PACKET_MARKER ) ? 3 : 8 );
78  }
79 
80 /* Scan a sequence of key packets to find the extent of the packet group. In
81  addition to simply scanning this function handles over-long packets by
82  reporting their overall length and returning OK_SPECIAL, and will try to
83  resync to a packet group if it starts in the middle of an arbitrary packet
84  collection, for example due to skipping of an over-long packet found
85  earlier */
86 
87 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
88 static int scanPacketGroup( INOUT STREAM *stream,
89  OUT_LENGTH_SHORT_Z int *packetGroupLength,
90  const BOOLEAN isLastGroup )
91  {
92  BOOLEAN firstPacket = TRUE, skipPackets = FALSE;
93  int endPos = 0, iterationCount, status = CRYPT_OK;
94 
95  assert( isReadPtr( stream, sizeof( STREAM ) ) );
96  assert( isWritePtr( packetGroupLength, sizeof( int ) ) );
97 
98  /* Clear return value */
99  *packetGroupLength = 0;
100 
101  for( iterationCount = 0; iterationCount < FAILSAFE_ITERATIONS_LARGE;
102  iterationCount++ )
103  {
104  long length;
105  int ctb, type;
106 
107  /* Get the next CTB. If it's the start of another packet group,
108  we're done */
109  ctb = status = sPeek( stream );
110  if( cryptStatusOK( status ) && !( pgpIsCTB( ctb ) ) )
111  status = CRYPT_ERROR_BADDATA;
112  if( cryptStatusError( status ) )
113  {
114  /* If we ran out of input data let the caller know, however if
115  this is the last packet group then running out of data isn't
116  an error */
117  if( status == CRYPT_ERROR_UNDERFLOW )
118  {
119  if( !isLastGroup )
120  skipPackets = TRUE;
121  break;
122  }
123  return( status );
124  }
125  type = pgpGetPacketType( ctb );
126  if( firstPacket )
127  {
128  /* If the packet group doesn't start with the expected packet
129  type, skip packets to try and resync */
130  if( type != PGP_PACKET_PUBKEY && type != PGP_PACKET_SECKEY )
131  skipPackets = TRUE;
132  firstPacket = FALSE;
133  }
134  else
135  {
136  /* If we've found the start of a new packet group, we're done */
137  if( type == PGP_PACKET_PUBKEY || type == PGP_PACKET_SECKEY )
138  break;
139  }
140 
141  /* Skip the current packet in the buffer */
142  status = pgpReadPacketHeader( stream, NULL, &length, \
143  getMinPacketSize( type ) );
144  if( cryptStatusOK( status ) )
145  {
146  endPos = stell( stream ) + length;
147  status = sSkip( stream, length );
148  }
149  if( cryptStatusError( status ) )
150  {
151  /* If we ran out of input data let the caller know */
152  if( status == CRYPT_ERROR_UNDERFLOW )
153  {
154  skipPackets = TRUE;
155  break;
156  }
157  return( status );
158  }
159  }
160  ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
161 
162  /* Remember where the current packet group ends. If we skipped packets
163  or consumed all of the input in the buffer and there's more present
164  beyond that, tell the caller to discard the data and try again */
165  *packetGroupLength = endPos;
166  return( skipPackets ? OK_SPECIAL : CRYPT_OK );
167  }
168 
169 /****************************************************************************
170 * *
171 * Process Key Packet Components *
172 * *
173 ****************************************************************************/
174 
175 /* Read the information needed to decrypt a private key */
176 
177 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
178 static int readPrivateKeyDecryptionInfo( INOUT STREAM *stream,
180  {
181  const int ctb = sgetc( stream );
182  int ivSize = 8, value, status;
183 
184  assert( isWritePtr( stream, sizeof( STREAM ) ) );
185  assert( isWritePtr( keyInfo, sizeof( PGP_KEYINFO ) ) );
186 
187  /* Clear return values */
188  keyInfo->cryptAlgo = keyInfo->hashAlgo = CRYPT_ALGO_NONE;
189  keyInfo->saltSize = keyInfo->keySetupIterations = 0;
190 
191  /* Before we go any further make sure that we were at least able to read
192  the CTB */
193  if( cryptStatusError( ctb ) )
194  return( ctb );
195 
196  /* If no encryption is being used we mark the key as unusable. This
197  isn't exactly the correct thing to do, but storing plaintext private
198  keys on disk is extremely dangerous and we probably shouldn't be
199  using them, and in any case an attempt to import an unencrypted key
200  will trigger so many security check failures in the key unwrap code
201  that it's not even worth trying */
202  if( ctb == 0 )
203  return( CRYPT_ERROR_NOSECURE );
204 
205  /* If it's a direct algorithm specifier then it's a PGP 2.x packet with
206  raw IDEA encryption */
207  if( ctb == PGP_ALGO_IDEA )
208  {
209  keyInfo->cryptAlgo = CRYPT_ALGO_IDEA;
210  keyInfo->hashAlgo = CRYPT_ALGO_MD5;
211  status = sread( stream, keyInfo->iv, ivSize );
212  if( cryptStatusError( status ) )
213  return( status );
214  keyInfo->ivSize = ivSize;
215 
216  return( CRYPT_OK );
217  }
218 
219  /* Must be an S2K specifier */
220  if( ctb != PGP_S2K && ctb != PGP_S2K_HASHED )
221  return( CRYPT_ERROR_BADDATA );
222 
223  /* Get the key wrap algorithm and S2K information. We have to save a
224  copy of the raw PGP algorithm ID for later examination to determine
225  the AES key size to use */
226  value = sPeek( stream );
227  status = readPgpAlgo( stream, &keyInfo->cryptAlgo,
229  if( cryptStatusError( status ) )
230  {
231  if( status == CRYPT_ERROR_NOTAVAIL )
232  {
233  /* Unknown algorithm type, skip this packet */
234  return( OK_SPECIAL );
235  }
236 
237  return( status );
238  }
239  if( keyInfo->cryptAlgo == CRYPT_ALGO_AES )
240  {
241  /* PGP uses three different algorithm IDs to identify AES with
242  different key sizes (ugh) so we have to remember the key size
243  alongside the algorithm type for this algorithm */
244  keyInfo->aesKeySize = ( value == PGP_ALGO_AES_128 ) ? 16 : \
245  ( value == PGP_ALGO_AES_192 ) ? 24 : 32;
246  ivSize = 16;
247  }
248  status = value = sgetc( stream );
249  if( cryptStatusError( status ) )
250  return( status );
251  if( value != 0 && value != 1 && value != 3 )
252  return( OK_SPECIAL );
253  status = readPgpAlgo( stream, &keyInfo->hashAlgo,
255  if( cryptStatusError( status ) )
256  {
257  if( status == CRYPT_ERROR_NOTAVAIL )
258  {
259  /* Unknown algorithm type, skip this packet */
260  return( OK_SPECIAL );
261  }
262 
263  return( status );
264  }
265  if( value != 0 )
266  {
267  /* It's a salted hash */
268  status = sread( stream, keyInfo->salt, PGP_SALTSIZE );
269  if( cryptStatusError( status ) )
270  return( status );
271  keyInfo->saltSize = PGP_SALTSIZE;
272  }
273  if( value == 3 )
274  {
275  long iterations;
276 
277  /* It's a salted iterated hash, get the iteration count, limited to
278  a sane value. The "iteration count" is actually a count of how
279  many bytes are hashed, this is because the "iterated hashing"
280  treats the salt + password as an infinitely-repeated sequence of
281  values and hashes the resulting string for PGP-iteration-count
282  bytes worth. The value that we calculate here (to prevent
283  overflow on 16-bit machines) is the count without the base * 64
284  scaling, this also puts the range within the value of the
285  standard sanity check. Note that there's a mutant GPG build used
286  with loop-AES that uses 8M setup iterations, why this is used and
287  why it writes PGP keys with this setting is uncertain but
288  cryptlib will reject keys with this value as being outside the
289  range of sane values (for an 8-byte salt and a typical 8-byte
290  password this would lead to 8M / 16 = 512K iterations of the PRF,
291  a value so extreme that it'd normally only be used in a DoS
292  attack).
293 
294  Unfortunately however PGP Desktop 9 (apparently) in its default
295  config will use values up to 4M (= 256K iterations of the PRF),
296  which the sanity-check code would also reject. It's uncertain at
297  which point we should draw the line here, on the one hand we want
298  to be able to handle PGP Desktop's data but we also want some
299  protection against DoS attacks due to ridiculously high iteration
300  counts. For now we reject obviously invalid values (ones less
301  than zero or which would cause an overflow once the base * 64
302  scaling is applied) and in addition tell the caller to skip the
303  packet (without rejecting the overall keyring data) if the
304  iteration count would be larger than 128K for the typical 8-byte
305  password case above */
306  value = sgetc( stream );
307  if( cryptStatusError( value ) )
308  return( value );
309  iterations = ( 16 + ( ( long ) value & 0x0F ) ) << ( value >> 4 );
310  if( iterations <= 0 || iterations >= MAX_INTLENGTH / 64 )
311  return( CRYPT_ERROR_BADDATA );
312  if( iterations >= 32768L ) /* 32K * 4 = 128K iterations */
313  return( OK_SPECIAL );
314  keyInfo->keySetupIterations = ( int ) iterations;
315  }
316  if( ctb == PGP_S2K_HASHED )
317  {
318  /* The legacy PGP 2.x key integrity protection format used a simple
319  16-bit additive checksum of the encrypted MPI payload, the newer
320  OpenPGP format uses a SHA-1 MDC. There's also a halfway format
321  used in older OpenPGP versions that still uses the 16-bit
322  checksum but encrypts the entire MPI data block rather than just
323  the payload */
324  keyInfo->hashedChecksum = TRUE;
325  }
326  status = sread( stream, keyInfo->iv, ivSize );
327  if( cryptStatusError( status ) )
328  return( status );
329  keyInfo->ivSize = ivSize;
330 
331  return( CRYPT_OK );
332  }
333 
334 /* Read public-key components */
335 
336 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
337 static int readPublicKeyComponents( INOUT STREAM *stream,
338  INOUT PGP_KEYINFO *keyInfo,
339  OUT_INT_Z int *pubKeyComponentLength )
340  {
341  int pgpPkcAlgo, length, totalLength = 1, status;
342  /* Initial length 1 is for the algorithm ID byte */
343 
344  assert( isWritePtr( stream, sizeof( STREAM ) ) );
345  assert( isWritePtr( keyInfo, sizeof( PGP_KEYINFO ) ) );
346  assert( isWritePtr( pubKeyComponentLength, sizeof( int ) ) );
347 
348  /* Clear return value */
349  *pubKeyComponentLength = 0;
350 
351  /* Get the public-key algorithm type */
352  status = pgpPkcAlgo = sgetc( stream );
353  if( cryptStatusError( status ) )
354  return( status );
355 
356  /* RSA: n + e. The LSBs of n serve as the PGP 2.x key ID so we copy the
357  data out before continuing */
358  if( pgpPkcAlgo == PGP_ALGO_RSA || pgpPkcAlgo == PGP_ALGO_RSA_ENCRYPT || \
359  pgpPkcAlgo == PGP_ALGO_RSA_SIGN )
360  {
361  keyInfo->pkcAlgo = CRYPT_ALGO_RSA;
362  if( pgpPkcAlgo != PGP_ALGO_RSA_SIGN )
363  keyInfo->usageFlags = KEYMGMT_FLAG_USAGE_CRYPT;
364  if( pgpPkcAlgo != PGP_ALGO_RSA_ENCRYPT )
365  keyInfo->usageFlags |= KEYMGMT_FLAG_USAGE_SIGN;
366  status = getMPIsize( stream, MIN_PKCSIZE, CRYPT_MAX_PKCSIZE,
367  &length ); /* n */
368  if( cryptStatusError( status ) )
369  return( status );
370  totalLength += length;
371  static_assert( PGP_KEYID_SIZE < MIN_PKCSIZE, "PGP keyID size" );
372 
373  /* Move back and copy out the last PGP_KEYID_SIZE bytes of n as the PGP
374  2.x key ID */
375  status = sseek( stream, stell( stream ) - PGP_KEYID_SIZE );
376  if( cryptStatusOK( status ) )
377  status = sread( stream, keyInfo->pgpKeyID, PGP_KEYID_SIZE );
378  if( cryptStatusOK( status ) )
379  status = getMPIsize( stream, 1, CRYPT_MAX_PKCSIZE, &length );
380  if( cryptStatusError( status ) ) /* e */
381  return( status );
382  *pubKeyComponentLength = totalLength + length;
383 
384  return( CRYPT_OK );
385  }
386 
387  /* If it's an unknown algorithm, skip this key */
388  if( pgpPkcAlgo != PGP_ALGO_DSA && pgpPkcAlgo != PGP_ALGO_ELGAMAL )
389  return( OK_SPECIAL );
390 
391  /* DSA/Elgamal: p + g + y. Note that we have to separate out the
392  getMPIsize() calls in order to serialise them otherwise some
393  optimising compilers will reorder the operations, causing the check
394  to fail because the parameters are different for the different MPI
395  values */
396  if( pgpPkcAlgo == PGP_ALGO_DSA )
397  {
398  keyInfo->pkcAlgo = CRYPT_ALGO_DSA;
399  keyInfo->usageFlags = KEYMGMT_FLAG_USAGE_SIGN;
400  }
401  else
402  {
403  keyInfo->pkcAlgo = CRYPT_ALGO_ELGAMAL;
404  keyInfo->usageFlags = KEYMGMT_FLAG_USAGE_CRYPT;
405  }
406  status = getMPIsize( stream, MIN_PKCSIZE, CRYPT_MAX_PKCSIZE, &length );
407  if( cryptStatusOK( status ) ) /* p */
408  {
409  totalLength += length;
410  status = getMPIsize( stream, 1, CRYPT_MAX_PKCSIZE, &length );
411  } /* g */
412  if( cryptStatusOK( status ) )
413  {
414  totalLength += length;
415  status = getMPIsize( stream, MIN_PKCSIZE, CRYPT_MAX_PKCSIZE,
416  &length ); /* y */
417  }
418  if( cryptStatusError( status ) )
419  return( status );
420  totalLength += length;
421  if( pgpPkcAlgo == PGP_ALGO_DSA )
422  {
423  /* DSA has q as well */
424  status = getMPIsize( stream, bitsToBytes( 155 ), CRYPT_MAX_PKCSIZE,
425  &length ); /* q */
426  if( cryptStatusError( status ) )
427  return( status );
428  totalLength += length;
429  }
430  *pubKeyComponentLength = totalLength;
431 
432  return( CRYPT_OK );
433  }
434 
435 /* Read a sequence of userID packets */
436 
438 static int readUserID( INOUT STREAM *stream,
439  INOUT_OPT PGP_INFO *pgpInfo,
440  INOUT_OPT HASHINFO *hashInfo )
441  {
442  HASHINFO localHashInfo;
443  long packetLength;
444  int ctb, packetType = DUMMY_INIT, iterationCount, status;
445 
446  assert( isWritePtr( stream, sizeof( STREAM ) ) );
447  assert( pgpInfo == NULL || \
448  isWritePtr( pgpInfo, sizeof( PGP_INFO ) ) );
449  assert( hashInfo == NULL || \
450  isWritePtr( hashInfo, sizeof( HASHINFO ) ) );
451 
452  /* Take a local copy of the hash information from the primary key
453  packet */
454  if( hashInfo != NULL )
455  memcpy( &localHashInfo, hashInfo, sizeof( HASHINFO ) );
456 
457  /* Skip keyring trust packets, signature packets, and any private
458  packets (GPG uses packet type 61, which might be a DSA self-
459  signature).
460 
461  PGP has two ways of indicating key usage, either directly via the key
462  type (e.g. PGP_ALGO_RSA_ENCRYPT vs. PGP_ALGO_RSA_SIGN) or in a rather
463  schizophrenic manner in signature packets by allowing the signer to
464  specify an X.509-style key usage. Since it can appear in both self-
465  sigs and certification signatures, the exact usage for a key is
466  somewhat complex to determine as a certification signer could
467  indicate that they trust the key when it's used for signing while a
468  self-signer could indicate that the key should be used for
469  encryption. This appears to be a preference indication rather than a
470  hard limit like the X.509 keyUsage and also contains other odds and
471  ends as well such as key splitting indicators. For now we don't make
472  use of these flags as it's a bit difficult to figure out what's what,
473  and in any case DSA vs. Elgamal doesn't need any further constraints
474  since there's only one usage possible */
475  for( status = CRYPT_OK, iterationCount = 0;
476  cryptStatusOK( status ) && iterationCount < FAILSAFE_ITERATIONS_MED;
477  iterationCount++ )
478  {
479  /* See what we've got. If we've run out of input or it's a non-key-
480  related packet, we're done */
481  status = ctb = sPeek( stream );
482  if( cryptStatusError( status ) )
483  break;
484  packetType = pgpGetPacketType( ctb );
485  if( packetType != PGP_PACKET_TRUST && \
486  packetType != PGP_PACKET_SIGNATURE && \
487  packetType != PGP_PACKET_USERATTR && \
488  !pgpIsReservedPacket( packetType ) )
489  break;
490 
491  /* Skip the packet. If we get an error at this point we don't
492  immediately bail out but try and return at least a partial
493  response */
494  status = pgpReadPacketHeader( stream, &ctb, &packetLength, \
495  getMinPacketSize( packetType ) );
496  if( cryptStatusError( status ) )
497  break;
498  status = sSkip( stream, packetLength );
499  }
500  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
501 
502  /* If we've reached the end of the current collection of key packets,
503  let the caller know that we're done. Note that running out of input
504  is a valid condition so we don't return a fatal error code at this
505  point */
506  if( cryptStatusError( status ) || packetType != PGP_PACKET_USERID )
507  return( OK_SPECIAL );
508 
509  /* Record the userID (unless we're skipping the packet). If there are
510  more userIDs than we can record we silently ignore them. This
511  handles keys with weird numbers of userIDs without rejecting them
512  just because they have, well, a weird number of userIDs */
513  status = pgpReadPacketHeader( stream, &ctb, &packetLength, \
514  getMinPacketSize( packetType ) );
515  if( cryptStatusError( status ) )
516  return( status );
517  if( pgpInfo != NULL && pgpInfo->lastUserID < MAX_PGP_USERIDS )
518  {
519  void *dataPtr;
520 
521  status = sMemGetDataBlock( stream, &dataPtr, packetLength );
522  if( cryptStatusError( status ) )
523  return( status );
524  pgpInfo->userID[ pgpInfo->lastUserID ] = dataPtr;
525  pgpInfo->userIDlen[ pgpInfo->lastUserID++ ] = ( int ) packetLength;
526  }
527  return( sSkip( stream, packetLength ) );
528  }
529 
530 /****************************************************************************
531 * *
532 * Read a Key *
533 * *
534 ****************************************************************************/
535 
536 /* Read a single key in a group of key packets. A packet group consists of
537  a jumble of packets concatenated together following a primary key with
538  the jumble continuing until we encounter another primary key, which is
539  why we need the auxiliary scanPacketGroup() function to look ahead in the
540  data stream to determine when to stop. A typical set of packets might be:
541 
542  DSA key
543  UserID
544  Binding signature of DSA key and UserID
545  Trust rating
546  Elgamal subkey
547  Binding signature of DSA key and Elgamal subkey
548  Trust rating
549 
550  but almost anything else is possible, there can be arbitrary further
551  userIDs, keys, and other data floating around, all glued together in
552  various locations with binding signatures (or possibly not, since the
553  signatures are optional).
554 
555  All of this is read into memory in a PGP_INFO structure with the
556  encoded data retained as follows:
557 
558  pgpInfo[ index ]->keyData = entire packet group
559  ->key->pubKeyData = DSA/RSA pubkey payload
560  ->key->privKeyData = DSA/RSA privkey payload (without
561  decryption information, which is
562  stored separately)
563  ->subKey->pubKeyData= Elgamal pubkey payload
564  ->subKey->privKeyData=Elgamal privkey as before.
565 
566  This tries to simplify things somewhat because in practice there can be a
567  more or less arbitrary number of subkeys present, not just the obvious
568  encryption subkeys signed with the primary signing key but also further
569  signing keys as subkeys, with a binding signature between the primary and
570  subkey made using the subkey instead of the primary key (although it can
571  also contain another binding signature from the primary key as well).
572 
573  The more or less arbitrarily complex nature of all of these bits and
574  pieces is why PGP 5, which used a keying format that was still vastly
575  simpler than the current one, was split into two separate applications
576  of which the more complex one did nothing but key handling and the other,
577  simpler one did everything else in PGP. It's also why we don't support
578  public keyring writes, it would require a complete keyring management
579  application just to deal with all of this complexity.
580 
581  Even just to read all of this stuff we have to simplify the processing a
582  bit by recording the first primary key and subkey and skipping anything
583  else that may be present, the addition of arbitrary numbers of further
584  subkeys each potentially with their own per-subkey userIDs is too complex
585  to handle without again building a complete key management application,
586  and in any case such oddball keys are fairly rare and the basic greedy
587  algorithm for handling them seems to work fine */
588 
589 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
590 static int readKey( INOUT STREAM *stream,
591  INOUT PGP_INFO *pgpInfo,
592  IN_INT_SHORT_Z const int keyGroupNo,
594  {
595  PGP_KEYINFO *keyInfo = &pgpInfo->key;
597  HASHINFO hashInfo;
598  BYTE hash[ CRYPT_MAX_HASHSIZE + 8 ], packetHeader[ 64 + 8 ];
599  BOOLEAN isPublicKey = TRUE, isPrimaryKey = FALSE;
600  void *pubKeyPayload;
601  long packetLength;
602  int pubKeyPos, pubKeyPayloadPos, endPos, pubKeyPayloadLen;
603  int ctb, length, value, hashSize, iterationCount, status;
604 
605  assert( isWritePtr( stream, sizeof( STREAM ) ) );
606  assert( isWritePtr( pgpInfo, sizeof( PGP_INFO ) ) );
607 
608  REQUIRES( keyGroupNo >= 0 && keyGroupNo < MAX_INTLENGTH_SHORT );
609  REQUIRES( errorInfo != NULL );
610 
611  /* Process the CTB and packet length */
612  ctb = sPeek( stream );
613  if( cryptStatusError( ctb ) )
614  {
615  /* If there was an error reading the CTB, which is the first byte of
616  the packet group, it means that we've run out of data so we
617  return the status as a not-found error rather than the actual
618  stream status */
619  return( CRYPT_ERROR_NOTFOUND );
620  }
621  switch( pgpGetPacketType( ctb ) )
622  {
624  keyInfo = &pgpInfo->subKey;
625  isPublicKey = FALSE;
626  break;
627 
628  case PGP_PACKET_SECKEY:
629  isPublicKey = FALSE;
630  break;
631 
633  keyInfo = &pgpInfo->subKey;
634  break;
635 
636  case PGP_PACKET_PUBKEY:
637  isPrimaryKey = TRUE;
638  break;
639 
640  default:
642  ( CRYPT_ERROR_BADDATA, errorInfo,
643  "Invalid PGP CTB %02X for key packet group %d",
644  ctb, keyGroupNo ) );
645  }
646  status = pgpReadPacketHeader( stream, NULL, &packetLength, 64 );
647  if( cryptStatusError( status ) )
648  {
649  retExt( status,
650  ( status, errorInfo,
651  "Invalid PGP key packet header for key packet group %d",
652  keyGroupNo ) );
653  }
654  if( packetLength < 64 || packetLength > sMemDataLeft( stream ) )
655  {
657  ( CRYPT_ERROR_BADDATA, errorInfo,
658  "Invalid PGP key packet length %ld for key packet group %d",
659  packetLength, keyGroupNo ) );
660  }
661 
662  /* Since there can (in theory) be arbitrary numbers of subkeys and other
663  odds and ends attached to a key and the details of what to do with
664  these things gets a bit vague, we just skip any further subkeys that
665  may be present */
666  if( keyInfo->pkcAlgo != CRYPT_ALGO_NONE )
667  {
668  status = sSkip( stream, packetLength );
669  for( iterationCount = 0;
670  cryptStatusOK( status ) && \
671  iterationCount < FAILSAFE_ITERATIONS_MED;
672  iterationCount++ )
673  {
674  status = readUserID( stream, pgpInfo,
675  isPrimaryKey ? &hashInfo : NULL );
676  }
677  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
678  if( cryptStatusError( status ) && status != OK_SPECIAL )
679  {
680  retExt( status,
681  ( status, errorInfo,
682  "Invalid additional PGP subkey information for key "
683  "packet group %d", keyGroupNo ) );
684  }
685  }
686 
687  /* Determine which bits make up the public and the private key data. The
688  public-key data starts at the version number and includes the date,
689  validity, and public-key components. Since there's no length
690  information included for this data block we have to record bookmarks
691  and then later retroactively calculate the length based on how much
692  data we've read in the meantime:
693 
694  pubKey pubKeyPayload privKey endPos
695  | | | |
696  v v v v
697  +---+---------------------------+-------------------+
698  |hdr| | Public key | Private key |
699  +---+---------------------------+-------------------+
700  | |<pubKeyPayloadLen->| |
701  |<----- pubKeyDataLen ----->|<-- privKeyDLen -->|
702  |<--------------- packetLength ---------------->| */
703  pubKeyPos = stell( stream );
704  endPos = pubKeyPos + packetLength;
705  ENSURES( endPos > pubKeyPos && endPos < MAX_INTLENGTH );
706  status = value = sgetc( stream );
707  if( cryptStatusError( status ) )
708  return( status );
709  if( value != PGP_VERSION_2 && value != PGP_VERSION_3 && \
710  value != PGP_VERSION_OPENPGP )
711  {
712  /* Unknown version number, skip this packet */
713  return( OK_SPECIAL );
714  }
715  pgpInfo->isOpenPGP = ( value == PGP_VERSION_OPENPGP ) ? TRUE : FALSE;
716 
717  /* Build the packet header, which is hashed along with the key components
718  to get the OpenPGP keyID. This is generated anyway when the context
719  is created but we need to generate it here as well in order to locate
720  the key in the first place:
721 
722  byte ctb = 0x99
723  byte[2] length
724  byte version = 4
725  byte[4] key generation time
726  [ byte[2] validity time - PGP 2.x only ]
727  byte[] key data
728 
729  We can't add the length or key data yet since we have to parse the
730  key data to know how long it is, so we can only build the static part
731  of the header at this point */
732  packetHeader[ 0 ] = 0x99;
733  packetHeader[ 3 ] = PGP_VERSION_OPENPGP;
734 
735  /* Read the timestamp and validity period (for PGP 2.x keys) */
736  status = sread( stream, packetHeader + 4, 4 );
737  if( !cryptStatusError( status ) && !pgpInfo->isOpenPGP )
738  status = sSkip( stream, 2 );
739  if( cryptStatusError( status ) )
740  return( status );
741 
742  /* Read the public key components */
743  pubKeyPayloadPos = stell( stream );
744  status = readPublicKeyComponents( stream, keyInfo, &length );
745  if( cryptStatusError( status ) )
746  {
747  /* If the error status is OK_SPECIAL then the problem was an
748  unrecognised algorithm or something similar so we just skip the
749  packet */
750  if( status == OK_SPECIAL )
751  {
752  DEBUG_DIAG(( "Encountered unrecognised algorithm while "
753  "reading key" ));
754  assert( DEBUG_WARN );
755  return( OK_SPECIAL );
756  }
757  retExt( status,
758  ( status, errorInfo,
759  "Invalid PGP public-key components for key packet group %d",
760  keyGroupNo ) );
761  }
762 
763  /* Now that we know where the public key data starts and finishes, we
764  can set up references to it */
765  keyInfo->pubKeyDataLen = stell( stream ) - pubKeyPos;
766  status = sMemGetDataBlockAbs( stream, pubKeyPos, &keyInfo->pubKeyData,
767  keyInfo->pubKeyDataLen );
768  if( cryptStatusError( status ) )
769  {
770  DEBUG_DIAG(( "Couldn't set up reference to key data" ));
771  assert( DEBUG_WARN );
772  return( status );
773  }
774  pubKeyPayloadLen = stell( stream ) - pubKeyPayloadPos;
775  status = sMemGetDataBlockAbs( stream, pubKeyPayloadPos, &pubKeyPayload,
776  pubKeyPayloadLen );
777  if( cryptStatusError( status ) )
778  {
779  DEBUG_DIAG(( "Couldn't set up reference to key data" ));
780  assert( DEBUG_WARN );
781  return( status );
782  }
783 
784  /* Complete the packet header that we read earlier on by adding the
785  length information */
786  packetHeader[ 1 ] = intToByte( ( ( 1 + 4 + length ) >> 8 ) & 0xFF );
787  packetHeader[ 2 ] = intToByte( ( 1 + 4 + length ) & 0xFF );
788 
789  /* Hash the data needed to generate the OpenPGP keyID */
790  getHashParameters( CRYPT_ALGO_SHA1, 0, &hashFunction, &hashSize );
791  hashFunction( hashInfo, NULL, 0, packetHeader, 1 + 2 + 1 + 4,
793  hashFunction( hashInfo, hash, CRYPT_MAX_HASHSIZE,
794  pubKeyPayload, pubKeyPayloadLen, HASH_STATE_END );
795  memcpy( keyInfo->openPGPkeyID, hash + hashSize - PGP_KEYID_SIZE,
796  PGP_KEYID_SIZE );
797 
798  /* If it's a private keyring, process the private key components */
799  if( !isPublicKey )
800  {
801  /* Handle decryption information for private-key components if
802  necessary */
803  status = readPrivateKeyDecryptionInfo( stream, keyInfo );
804  if( cryptStatusError( status ) )
805  {
806  /* If the error status is OK_SPECIAL then the problem was an
807  unrecognised algorithm or something similar so we just skip
808  the packet */
809  if( status == OK_SPECIAL )
810  {
811  DEBUG_DIAG(( "Encountered unrecognised algorithm while "
812  "reading key" ));
813  assert( DEBUG_WARN );
814  return( OK_SPECIAL );
815  }
816  retExt( status,
817  ( status, errorInfo,
818  "Invalid PGP private-key decryption information for "
819  "key packet group %d", keyGroupNo ) );
820  }
821 
822  /* What's left is the private-key data */
823  keyInfo->privKeyDataLen = endPos - stell( stream );
824  status = sMemGetDataBlock( stream, &keyInfo->privKeyData,
825  keyInfo->privKeyDataLen );
826  if( cryptStatusOK( status ) )
827  status = sSkip( stream, keyInfo->privKeyDataLen );
828  if( cryptStatusError( status ) )
829  return( status );
830  }
831 
832  /* If it's the primary key, start hashing it in preparation for
833  performing signature checks on subpackets */
834  if( isPrimaryKey )
835  {
836  packetHeader[ 0 ] = 0x99;
837  packetHeader[ 1 ] = intToByte( ( keyInfo->pubKeyDataLen >> 8 ) & 0xFF );
838  packetHeader[ 2 ] = intToByte( keyInfo->pubKeyDataLen & 0xFF );
839  hashFunction( hashInfo, NULL, 0, packetHeader, 1 + 2,
841  hashFunction( hashInfo, NULL, 0, keyInfo->pubKeyData,
843  }
844 
845  /* Read any associated subpacket(s), of which the only ones of real
846  interest are the userID packet(s) */
847  for( iterationCount = 0;
848  cryptStatusOK( status ) && \
849  iterationCount < FAILSAFE_ITERATIONS_MED;
850  iterationCount++ )
851  {
852  status = readUserID( stream, pgpInfo,
853  isPrimaryKey ? &hashInfo : NULL );
854  }
855  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
856  if( cryptStatusError( status ) && status != OK_SPECIAL )
857  {
858  retExt( status,
859  ( status, errorInfo,
860  "Invalid PGP userID information for key packet group %d",
861  keyGroupNo ) );
862  }
863 
864  /* If there's no user ID present, set a generic label */
865  if( pgpInfo->lastUserID <= 0 )
866  {
867  pgpInfo->userID[ 0 ] = "PGP key (no user ID found)";
868  pgpInfo->userIDlen[ 0 ] = 26;
869  pgpInfo->lastUserID = 1;
870  }
871 
872  return( CRYPT_OK );
873  }
874 
875 /* Process the information in the packet group */
876 
877 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 6 ) ) \
878 static int processPacketGroup( INOUT STREAM *stream,
879  INOUT PGP_INFO *pgpInfo,
882  IN_INT_SHORT_Z const int keyGroupNo,
883  INOUT ERROR_INFO *errorInfo )
884  {
885  int iterationCount, status;
886 
887  assert( isWritePtr( stream, sizeof( STREAM ) ) );
888  assert( isWritePtr( pgpInfo, sizeof( PGP_INFO ) ) );
889  assert( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
890  ( isReadPtr( keyMatchInfo, sizeof( KEY_MATCH_INFO ) ) && \
891  isWritePtr( matchedKeyInfoPtrPtr, sizeof( PGP_KEYINFO * ) ) ) );
892 
893  REQUIRES( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
894  ( keyMatchInfo != NULL && matchedKeyInfoPtrPtr != NULL && \
895  pgpInfo->keyData != NULL && \
896  pgpInfo->keyDataLen == KEYRING_BUFSIZE ) );
897  REQUIRES( keyGroupNo >= 0 && keyGroupNo < MAX_INTLENGTH_SHORT );
898  REQUIRES( errorInfo != NULL );
899 
900  /* Clear the index information before we read the current key(s), since
901  it may already have been initialised during a previous (incomplete)
902  key read */
903  memset( &pgpInfo->key, 0, sizeof( PGP_KEYINFO ) );
904  memset( &pgpInfo->subKey, 0, sizeof( PGP_KEYINFO ) );
905  memset( pgpInfo->userID, 0, sizeof( char * ) * MAX_PGP_USERIDS );
906  memset( pgpInfo->userIDlen, 0, sizeof( int ) * MAX_PGP_USERIDS );
907  pgpInfo->lastUserID = 0;
908 
909  /* Read all the packets in this packet group */
910  for( status = CRYPT_OK, iterationCount = 0;
911  cryptStatusOK( status ) && sMemDataLeft( stream ) > 0 && \
912  iterationCount++ < FAILSAFE_ITERATIONS_MED;
913  iterationCount++ )
914  {
915  status = readKey( stream, pgpInfo, keyGroupNo, errorInfo );
916  }
917  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
918  if( cryptStatusError( status ) )
919  {
920  if( status != OK_SPECIAL && status != CRYPT_ERROR_NOSECURE )
921  return( status );
922 
923  /* There's either something in the key information that we can't
924  handle or it's stored with no security, skip the key */
925  if( keyMatchInfo == NULL )
926  pgpFreeEntry( pgpInfo );
927  return( status );
928  }
929 
930  /* If we're reading all keys, we're done */
931  if( keyMatchInfo == NULL )
932  return( CRYPT_OK );
933 
934  /* We're searching for a particular key, see if this is the one */
935  if( pgpCheckKeyMatch( pgpInfo, &pgpInfo->key, keyMatchInfo ) )
936  {
937  *matchedKeyInfoPtrPtr = &pgpInfo->key;
938  return( CRYPT_OK );
939  }
940  if( pgpCheckKeyMatch( pgpInfo, &pgpInfo->subKey, keyMatchInfo ) )
941  {
942  *matchedKeyInfoPtrPtr = &pgpInfo->subKey;
943  return( CRYPT_OK );
944  }
945 
946  /* No match, tell the caller to keep looking */
947  return( CRYPT_ERROR_NOTFOUND );
948  }
949 
950 /****************************************************************************
951 * *
952 * Read a Keyring *
953 * *
954 ****************************************************************************/
955 
956 /* Read an entire keyring. This function can be used in one of two ways, if
957  key match information is supplied each packet will be checked against it
958  and the read will exit when a match is found (used for public keyrings).
959  If no key match information is supplied, all keys will be read into
960  memory (used for private keyrings) */
961 
962 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4, 8, 9 ) ) \
963 static int processKeyringPackets( INOUT STREAM *stream,
964  IN_ARRAY( maxNoPgpObjects ) PGP_INFO *pgpInfo,
967  IN_LENGTH_SHORT_MIN( 64 ) const int bufSize,
968  IN_OPT const KEY_MATCH_INFO *keyMatchInfo,
969  INOUT_OPT PGP_KEYINFO **matchedKeyInfoPtrPtr,
970  OUT BOOLEAN *unhandledDataPresent,
971  INOUT ERROR_INFO *errorInfo )
972  {
973  BYTE streamBuffer[ STREAM_BUFSIZE + 8 ];
974  BOOLEAN moreData, insecureKeys = FALSE;
975  int bufEnd, keyGroupNo = 0, iterationCount, status;
976 
977  assert( isWritePtr( stream, sizeof( STREAM ) ) );
978  assert( isWritePtr( pgpInfo, sizeof( PGP_INFO ) * maxNoPgpObjects ) );
979  assert( isWritePtr( buffer, bufSize ) );
980  assert( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
981  ( isReadPtr( keyMatchInfo, sizeof( KEY_MATCH_INFO ) ) && \
982  isWritePtr( matchedKeyInfoPtrPtr, sizeof( PGP_KEYINFO * ) ) ) );
983  assert( isWritePtr( unhandledDataPresent, sizeof( BOOLEAN ) ) );
984 
985  REQUIRES( maxNoPgpObjects >= 1 && maxNoPgpObjects < MAX_INTLENGTH_SHORT );
986  REQUIRES( bufSize > 64 && bufSize < MAX_INTLENGTH_SHORT );
987  REQUIRES( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
988  ( keyMatchInfo != NULL && matchedKeyInfoPtrPtr != NULL && \
989  pgpInfo->keyData != NULL && \
990  pgpInfo->keyDataLen == KEYRING_BUFSIZE ) );
991  REQUIRES( errorInfo != NULL );
992 
993  /* Clear return value */
994  *unhandledDataPresent = FALSE;
995 
996  /* Scan all of the objects in the keyset. This is implemented as a
997  sliding window that reads a certain amount of data into a lookahead
998  buffer and then tries to identify a packet group in the buffer. If
999  we need to skip packets (for example due to unknown algorithms) we
1000  mark the keyset as read-only since it's no longer safe for us to
1001  write the incompletely-processed data to disk */
1002  sioctlSetString( stream, STREAM_IOCTL_IOBUFFER, streamBuffer,
1003  STREAM_BUFSIZE );
1004  for( moreData = TRUE, bufEnd = 0, iterationCount = 0;
1005  ( moreData || bufEnd > 0 ) && \
1006  iterationCount < FAILSAFE_ITERATIONS_MAX;
1007  iterationCount++ )
1008  {
1009  PGP_INFO *pgpInfoPtr = &pgpInfo[ keyGroupNo ];
1010  STREAM keyStream;
1011  int length = DUMMY_INIT; /* Init needed by gcc */
1012 
1013  /* Fill the lookahead buffer:
1014 
1015  buffer bufEnd bufSize
1016  | | |
1017  v v v
1018  +-----------+---------------+
1019  |///////////| |
1020  +-----------+---------------+
1021  |
1022  +-- length --> */
1023  if( moreData )
1024  {
1025  REQUIRES( bufEnd >= 0 && bufEnd < bufSize );
1026 
1027  status = length = sread( stream, buffer + bufEnd,
1028  bufSize - bufEnd );
1029  if( status <= 0 )
1030  {
1031  /* If we read nothing and there's nothing left in the buffer,
1032  we're done */
1033  if( bufEnd <= 0 )
1034  {
1035  /* If we've previously read at least one group of key
1036  packets, we're OK */
1037  if( keyGroupNo > 0 )
1038  status = CRYPT_OK;
1039  return( status );
1040  }
1041 
1042  /* There's still data in the buffer, we can continue until
1043  we drain it */
1044  length = 0;
1045  }
1046  if( length < bufSize - bufEnd )
1047  {
1048  /* We didn't get as much as we requested, there's nothing
1049  left to read */
1050  moreData = FALSE;
1051  }
1052  bufEnd += length;
1053  }
1054 
1055  /* Determine the size of the group of key packets in the buffer */
1056  sMemConnect( &keyStream, buffer, bufEnd );
1057  status = scanPacketGroup( &keyStream, &length, !moreData );
1058  sMemDisconnect( &keyStream );
1059  if( status == OK_SPECIAL )
1060  {
1061  /* Remember that we hit something that we couldn't process */
1062  *unhandledDataPresent = TRUE;
1063 
1064  /* If the packet group is contained within the buffer, remove
1065  the problem packets and continue */
1066  if( length <= bufEnd )
1067  {
1068  if( bufEnd - length > 0 )
1069  {
1070  REQUIRES( rangeCheck( length, bufEnd - length,
1071  bufSize ) );
1072  memmove( buffer, buffer + length, bufEnd - length );
1073  }
1074  bufEnd -= length;
1075  continue;
1076  }
1077  ENSURES( length > bufEnd );
1078 
1079  /* The packet group overflows the buffer, skip the remaining
1080  contents and continue */
1081  status = sseek( stream, stell( stream ) + ( length - bufEnd ) );
1082  if( cryptStatusError( status ) )
1083  break;
1084  bufEnd = 0;
1085  continue;
1086  }
1087  if( cryptStatusError( status ) )
1088  {
1089  retExt( status,
1090  ( status, errorInfo,
1091  "Couldn't parse key packet group %d", keyGroupNo ) );
1092  }
1093  if( length <= 0 )
1094  return( CRYPT_OK );
1095 
1096  /* Move the packet group from the keyring buffer to the key data */
1097  if( keyMatchInfo == NULL )
1098  {
1099  /* It's a read of all packets, allocate room for the current
1100  packet group */
1101  if( ( pgpInfoPtr->keyData = \
1102  clAlloc( "readKeyring", length ) ) == NULL )
1103  return( CRYPT_ERROR_MEMORY );
1104  pgpInfoPtr->keyDataLen = length;
1105  }
1106  memcpy( pgpInfoPtr->keyData, buffer, length );
1107  if( bufEnd > length )
1108  {
1109  REQUIRES( rangeCheck( length, bufEnd - length, bufSize ) );
1110  memmove( buffer, buffer + length, bufEnd - length );
1111  }
1112  bufEnd -= length;
1113 
1114  /* Process the current packet group */
1115  sMemConnect( &keyStream, pgpInfoPtr->keyData, length );
1116  status = processPacketGroup( &keyStream, pgpInfoPtr, keyMatchInfo,
1117  matchedKeyInfoPtrPtr, keyGroupNo,
1118  errorInfo );
1119  sMemDisconnect( &keyStream );
1120  if( cryptStatusError( status ) )
1121  {
1122  /* If we were looking for a match for a particular key and
1123  didn't find it, continue */
1124  if( keyMatchInfo != NULL && status == CRYPT_ERROR_NOTFOUND )
1125  continue;
1126 
1127  /* If it's not a recoverable error, exit */
1128  if( status != OK_SPECIAL && status != CRYPT_ERROR_NOSECURE )
1129  return( status );
1130 
1131  /* Remember that we hit something that we couldn't process, and
1132  optionally an (unusable) unprotected key */
1133  *unhandledDataPresent = TRUE;
1134  if( status == CRYPT_ERROR_NOSECURE )
1135  insecureKeys = TRUE;
1136  continue;
1137  }
1138 
1139  /* If we're looking for a particular key, we've found it */
1140  if( keyMatchInfo != NULL )
1141  return( CRYPT_OK );
1142 
1143  /* We're reading all keys, move on to the next empty slot. Note
1144  that we only get to this point if we've been able to do something
1145  with the key, if not then the unhandledDataPresent flag is set
1146  without moving on to the next key group */
1147  keyGroupNo++;
1148  if( keyGroupNo >= maxNoPgpObjects )
1149  {
1151  ( CRYPT_ERROR_OVERFLOW, errorInfo,
1152  "Maximum keyset object item count %d reached, no more "
1153  "room to add further items", maxNoPgpObjects ) );
1154  }
1155  }
1156  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
1157 
1158  /* If we were looking for a specific match, we haven't found it */
1159  if( keyMatchInfo != NULL )
1160  return( CRYPT_ERROR_NOTFOUND );
1161 
1162  /* If we haven't found any keys that we can use let the caller know.
1163  The error code to return here is a bit complex because we can skip
1164  keys either because there's something in the key data that we can't
1165  process or because the keys aren't sufficiently protected for us to
1166  trust them. The most complex case is when both situations occur.
1167  To keep it simple, if there are any insecure keys then we report
1168  CRYPT_ERROR_NOSECURE on the basis that if the keys had been
1169  appropriately secured then we might have been able to process them
1170  and return one */
1171  if( keyGroupNo <= 0 )
1172  {
1173  return( insecureKeys ? CRYPT_ERROR_NOSECURE : \
1175  }
1176 
1177  return( CRYPT_OK );
1178  }
1179 
1180 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 6 ) ) \
1181 int pgpReadKeyring( INOUT STREAM *stream,
1182  IN_ARRAY( maxNoPgpObjects ) PGP_INFO *pgpInfo,
1183  IN_LENGTH_SHORT const int maxNoPgpObjects,
1184  IN_OPT const KEY_MATCH_INFO *keyMatchInfo,
1185  INOUT_OPT PGP_KEYINFO **matchedKeyInfoPtrPtr,
1186  INOUT ERROR_INFO *errorInfo )
1187  {
1188  BOOLEAN unhandledDataPresent;
1189  BYTE *buffer;
1190  int status;
1191 
1192  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1193  assert( isWritePtr( pgpInfo, sizeof( PGP_INFO ) * maxNoPgpObjects ) );
1194  assert( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
1195  ( isReadPtr( keyMatchInfo, sizeof( KEY_MATCH_INFO ) ) && \
1196  isWritePtr( matchedKeyInfoPtrPtr, sizeof( PGP_KEYINFO * ) ) ) );
1197 
1198  REQUIRES( maxNoPgpObjects >= 1 && maxNoPgpObjects < MAX_INTLENGTH_SHORT );
1199  REQUIRES( ( keyMatchInfo == NULL && matchedKeyInfoPtrPtr == NULL ) || \
1200  ( keyMatchInfo != NULL && matchedKeyInfoPtrPtr != NULL && \
1201  pgpInfo->keyData != NULL && \
1202  pgpInfo->keyDataLen == KEYRING_BUFSIZE ) );
1203  REQUIRES( errorInfo != NULL );
1204 
1205  /* Clear the return value */
1206  if( matchedKeyInfoPtrPtr != NULL )
1207  *matchedKeyInfoPtrPtr = NULL;
1208 
1209  /* Since PGP keyrings just contain an arbitrary collection of packets
1210  concatenated together we can't tell in advance how much data we
1211  should be reading. Because of this we have to set the file stream to
1212  allow partial reads without returning a read error */
1213  if( ( buffer = clAlloc( "readKeyring", KEYRING_BUFSIZE ) ) == NULL )
1214  return( CRYPT_ERROR_MEMORY );
1215  sioctlSet( stream, STREAM_IOCTL_PARTIALREAD, TRUE );
1216  status = processKeyringPackets( stream, pgpInfo, maxNoPgpObjects,
1217  buffer, KEYRING_BUFSIZE,
1218  keyMatchInfo, matchedKeyInfoPtrPtr,
1219  &unhandledDataPresent, errorInfo );
1220  sioctlSet( stream, STREAM_IOCTL_IOBUFFER, 0 );
1221  clFree( "readKeyring", buffer );
1222  if( cryptStatusError( status ) )
1223  return( status );
1224 
1225  /* If we couldn't process one or more packets let the caller know that
1226  not all keyring data is present in memory */
1227  return( unhandledDataPresent ? OK_SPECIAL : CRYPT_OK );
1228  }
1229 #endif /* USE_PGPKEYS */